Make use of an old CGA monitor - Page 1
Forum section: electronics / projects

author: npelov
author_rank: Frequent Contributor
timestamp: May 12, 2015, 03:10:51 pm
content: Hi,I have an old CGA monitor from a 16 bit XT. I also have the video card. I couldn't throw it in the trash - it's from my first PC. No one wanted it for making an oscilloscope. I know it's easier to put a small SPI LCD than driving this monitor but I wish I use it for something. My question is:Should I try to use the 8 bit ISA CGA video card by driving the ISA bus or I should try to drive the monitor directly.It has 9 pin CGA connector with H-sync, V-sync and RGBI (1 bit each) inputs. Of course it's a black and white (or I should say green) monitor, so it'll only show gray shades. But I might only use it as monochrome anyway. I wish I can drive the ISA bus because the video card will save me some CPU time (at expense of a lot of space and power consumption).So if someone can give me links to 8 bit ISA specification, timing diagrams or whatever can help meI would be grateful.I hate wasting time, but I just could let this one go...

author: Fungus
author_rank: Super Contributor
timestamp: May 12, 2015, 03:21:25 pm
content: Quote from: npelov on May 12, 2015, 03:10:51 pmAdd another CPU :-)(which is what your ISA card really is...)

author: German_EE
author_rank: Super Contributor
timestamp: May 12, 2015, 03:33:28 pm
content: You should be able to connect this to a PC:1) Using a modern monitor set your PC to 640 x 480. This step is needed because a monitor this old cannot automatically negotiate a connection.2) Horizontal and vertical sync connect as normal.3) As you have a monochrome monitor connect the red, green and blue outputs through 75 ohm resistors to the monitor. This is just for safety, I feel a little uncomfortable with the R, G and B signals directly shorted together at the monitor.Your only problem is going to be making up the 15-pin to 9-pin cable

author: Fungus
author_rank: Super Contributor
timestamp: May 12, 2015, 03:37:16 pm
content: You could drive it from an Arduino.There's lots of info on doing that out there on the web.(Actually they usually do VGA...CGA will be a fun hack)

author: technix
author_rank: Super Contributor
timestamp: May 12, 2015, 04:58:28 pm
content: Quote from: npelov on May 12, 2015, 03:10:51 pm8-bit ISA is exactly the pins you would find on the original 8086/8088 chips, consult those if you need help.Just for fun, if you dare, you can put the OpenCores 80486 reimplementation onto a FPGA, clock it at 133MHz core frequency and and drive your ISA video card and CGA screen using that, running some kind of DOS.

author: npelov
author_rank: Frequent Contributor
timestamp: May 13, 2015, 12:25:31 pm
content: Quote from: Fungus on May 12, 2015, 03:37:16 pmYes, I found lots of VGA stuff. But VGA is more complex because often they have a bios that initializes the card and it's an i386 (or at least x86) code. Making an x86 interpreter is not an easy job. But I couldn't find any CGA video card driving attempts on the net...

author: npelov
author_rank: Frequent Contributor
timestamp: May 13, 2015, 12:29:54 pm
content: Quote from: technix on May 12, 2015, 04:58:28 pmI don't quite have that much of experience on x86 architecture. If I had I wouldn't have problems of driving simple 8 bit ISA slot. And the 486 has a ton of pins. Won't be easy to write it. So I don't dare.I'm not aware of those OpenCores CPUs. Are they something like system on chip with built-in ram and other controllers or a bare CPU?

author: Fungus
author_rank: Super Contributor
timestamp: May 13, 2015, 12:30:06 pm
content: Quote from: npelov on May 13, 2015, 12:25:31 pmThey drive the monitor directly from the Arduino pins. No graphics card needed.CGA is much easier because it has TTL inputs, not analog.Edit: Take a look at TVout to get an idea:https://code.google.com/p/arduino-tvout/CGA will be slightly easier because the horizontal/vertical sync are on separate wires.

author: Lightages
author_rank: Unknown
timestamp: May 13, 2015, 12:32:59 pm
content: If you really want to just make use of the monitor then bypass the CGA logic and use the analog inputs inside. Some of these monitors have a normal RGB input inside with a CGA front end tacked on.

author: npelov
author_rank: Frequent Contributor
timestamp: May 13, 2015, 12:43:03 pm
content: Quote from: Fungus on May 12, 2015, 03:21:25 pmGood point! I kinda though about this right after I wrote that sentence. But I still haven't made the calculations of what resolution can I get from a MCU. If I were more into the FPGA stuff I would make a video card that I can talk to with a MCU, but MCU themselves are not that good of driving fast signals and taking commands at the same time. I've seen people over the net getting an NTSC video signal out of atmel MCU, but at quite coarse resolution.I'm still holding back on this until I have some more information. I'm willing to waste some time, but not too much. I kinda miss the green, eye burning stuff from my childhood.Quote from: Lightages on May 13, 2015, 12:32:59 pmWell yes, but why? CGA is actually easier to drive than RGB (or whatever it's called in B/W monitors). There is no much difference if I just want monochrome. One reason to bypass it is to make an oscilloscope or something like this. But that's a game for ones that doesn't already have one. I'm not sure what else can I make from fully analog drive of a CRT.

author: npelov
author_rank: Frequent Contributor
timestamp: May 13, 2015, 01:24:07 pm
content: Ok. Let me ask more specific questions. Info I find on wikipedia:http://en.wikipedia.org/wiki/Color_Graphics_Adaptershows 60Hz vertical frequency, which I understand as 60 frames/sec. and 15.75kHz horizontal frequency, which I translate as 15750 rows a second. That's 262.5 rows per frame. Now my best guess is that the time for displaying 62.5 rows should be the time for the beam going back to the top of screen...?Am I thinking correctly? I don't really have any experience with TVs ...So is the H and V sync output from the monitor?Let me calculate dot frequency for 320x200. 15.75k*320 = 5.04MHz, except that you might need to wait for the beam to go back to the left side after drawing a row. Sounds hard to achieve. Maybe with a SPI I can throw series of 5MHz 8 bits and make a character display ...

author: T3sl4co1l
author_rank: Super Contributor
timestamp: May 13, 2015, 01:47:08 pm
content: CGA modes were 320x200 and 640x200 (yeech, the aspect ratio!). And also oddballs like 160x200 and 160x100 that you could coax with register abuse (occasionally used in Demoscene programs), providing a few more colors. Text was 40x25 or 80x25 characters, with pixel resolution same as above.In any case, the refresh rates were largely the same, as noted. So, the extra 60ish lines went to retrace and overscan, and ditto for the extra horizontal pixels. Master clock on those systems was usually something like 4.77MHz I think?Sync comes from the PC; the monitor synchronizes its internal oscillators based on this. (It usually takes a few cycles before the oscillator locks onto a new signal, or a sudden change, hence why it can take some time for vertical sweep to roll and lock, or twitch out and stretch or compress momentarily, when switching resolutions on multiscan monitors.) Occasionally, register abuse could also produce inconvenient sync pulses, which under or over-clock the monitor, leading to "fatal poke" or 0xf00f commands.Tim

author: Fungus
author_rank: Super Contributor
timestamp: May 13, 2015, 02:04:02 pm
content: Quote from: npelov on May 13, 2015, 01:24:07 pmYou're not far off.I think CGA has some unused lines as 'border' as well as vertical blanking.

author: Fungus
author_rank: Super Contributor
timestamp: May 13, 2015, 02:06:12 pm
content: Quote from: npelov on May 13, 2015, 01:24:07 pmYes, the Arduino TVout library I mentioned earlier uses SPI to output the bits.(it's the only way to have zero gap between each block of 8 bits).

author: npelov
author_rank: Frequent Contributor
timestamp: May 13, 2015, 02:45:00 pm
content: starting to get some data ... So, monitor locks to the sync signals of the PC. Good. I wander how much can I underclock it. I probably can't make it run at half the H-sync frequency, can I? It would be too easy. 160x100 might be doable with enough CPU time left. I'll have to find some free time to play with that. I might also use the back trace of the beam to do some communication.Well, I don't know why I feel more comfortable with using the CGA video card. Maybe because you can write whenever you want and it won't complain it's busy with tracing right now.

author: npelov
author_rank: Frequent Contributor
timestamp: May 23, 2015, 08:38:57 am
content: Does anyone know thetiminglength of CGA V and H sync pulses? This guy measured it for VGA:http://www.gammon.com.au/forum/?id=11608But I don't have working CGA hardware.

author: rob77
author_rank: Super Contributor
timestamp: May 23, 2015, 10:53:16 am
content: i would connect the graphics card to a micro/arduino (however arduino's digitalwrite might be dead-slow to drive the ISA signals)..here is a nice description of pinout, signals and also timing diagrams and transfer modes...http://pinouts.ru/Slots/isa_pinout.shtmlit should be doable because there are some implementations of ISA ethernet + micro out there.

author: amyk
author_rank: Super Contributor
timestamp: May 23, 2015, 12:59:05 pm
content: Bit-banging a VGA signal with a single microcontroller:http://www.linusakesson.net/scene/craft/It shouldn't be too hard to do the same for CGA.

author: npelov
author_rank: Frequent Contributor
timestamp: May 23, 2015, 01:40:04 pm
content: Well, I did actually use VGA H and V sync pulse width for CGA. After all there is aCGA to VGA cablemade.So it works. I made H-Sync, V-Sync and Line signals - I light up every other line. I left 30 black lines after V-Sync and there should be about 30 black lines after line number 200.

author: npelov
author_rank: Frequent Contributor
timestamp: May 23, 2015, 02:25:32 pm
content: And that's the resolution you can get without using SPI. I'm toggling pixel data, leaving every 8 lines off. So it's something like chessboard. The width of a block is the pixel width!!! The height of a block is 8 lines. So you can get a resolution 42x200. Of course if you have to get real data to display ... that'll go down on X. So next step - the SPI.@rob77 Using isa is actually faster than trying to output the video signal directly, because you send the pixels to the video card and you can then do whatever you want while the video card is rendering the dispaly. Thanks for the link. I'll read it.

author: T3sl4co1l
author_rank: Super Contributor
timestamp: May 23, 2015, 03:41:52 pm
content: What MCU platform and toolchain are you using?I should think it's possible to get >= 256 monochrome pixels by bit-banging from something like AVR at a clock over 6MHz. With maximum 16 to 32MHz available (between MEGA and XMEGA), there should be enough time to refresh registers between lines and read in more RAM/ROM, maybe not allowing completely fresh image data per line, but I can imagine repeating lines or slowly changing data (including possible compression methods).Microcontrollers have very little onboard RAM anyway, so it might be very worthwhile to investigate e.g. abusing SPI RAM as a video generator, maybe with a little outboard logic (shift registers to buffer and re-align poorly timed frames?).Tim

author: amyk
author_rank: Super Contributor
timestamp: May 23, 2015, 03:46:30 pm
content: Great, now write a demo for it.

author: npelov
author_rank: Frequent Contributor
timestamp: May 23, 2015, 04:04:01 pm
content: @T3sl4co1l I use PIC18F45K22. It's running at 16 MIPS at 64MHz. I know AVR instructions have some advantages, but I think you are overstating the power of AVR. 6 MHz with instruction clock (if I remember correctly) of 3 MHz -> that's 330ns per instruction. The H clock is 15.625 kHz (rounded) - that's 64us per line. You have about 10-20% dead zone - that's at most 57us per line. So you are telling me that with 6 MHz clock, which is 0.33 us you can get 256 dots. 57/0.3333 is 171. And that's only if you have 1 instruction per dot. Can you read 171 bits and output them to a pin in 171 instruction cycles? I don't think so.The best would be if you have SPI hardware with output shift register double buffered. Unfortunately PIC only has double buffering for receive register. And even then you are pretty limited of what you can do with the rest of the CPU time. I would prefer if I can make the ISA card working, but my knowledge of x86 arch. is not that good.Attachment is showing usage of SPI at 4 MHz. There is 1 instruction deadtime - vertical black lines. I think I can run the SPI at 8 MHz if I optimize the quickly written code or even write it in assembler, I can do nothing to get rid of the deadtime.

author: npelov
author_rank: Frequent Contributor
timestamp: May 23, 2015, 04:20:13 pm
content: Quote from: amyk on May 23, 2015, 03:46:30 pmI don't think so. A demo means "I spent a month of trying to squeeze all the juice from my MCU to create a funny, useless animation. Making this monitor work is also waste of time because you can display something cheaper, easier, faster, more energy efficient with today's displays. But if I'm going to spend that time I'll want to have something useful. Like 80x25 character display.There is one problem though. The thing is screaming with 16 KHz and my head is going to explode soon. I wonder can you reduce the noise... Is it coming from the beam deflection coils? Can I pot it with resin?P.S. It's consuming 39W. Not that bad. My LCD is consuming 32W.

author: T3sl4co1l
author_rank: Super Contributor
timestamp: May 23, 2015, 06:09:27 pm
content: Quote from: npelov on May 23, 2015, 04:04:01 pmAVR is single cycle (reg-reg instructions). RAM is usually slower, and instruction store to reg, even slower (also branches, if taken).My baseline idea would be, fill up all 32 byte registers with the next line, and transmit each one in sequence to the desired pin. Which might look something like,PA0 = output, others = junkCode:MACRO FOR N = 0 TO 31MACRO REPEAT(8)OUT PORTA, r{N}LSR r{N}END MACROEND MACROwhere "REPEAT" means, write this out 8 times, and FOR does the same thing but incrementing "N". Compile-time macros, so, the code space to write out one single line becomes huge (each instruction is one WORD, so you'd need 8 x 32 = 256 WORDs (512 bytes) to do it!).But hey, when you have 64k of program memory and only 2k of RAM...AVR has the nice feature of having 32 x 8 bit registers, so you could potentially store 256 bits in the registers, all at once. Maybe more, depending on how desperate you want to get -- don't forget that all those IO ports are registers too, even the FLAGS register. You could do some seriously demented stuff to the peripherals, which is fine because who needs 'em anyway?You probably would not be able to read in much RAM/ROM during horizontal retrace, so you'd want to figure some way to make the lines change only a few bytes at a time.Or since we're just writing all this damn stuff out as code anyway, the refresh instructions could be generated by an image compression routine that converts line-to-line changes into limited register updates, or varies the actual 'copy register to port' instructions in the program (which could take tremendously more code space as a result, however). In other words, something very much in the style of the PC-XT "full speed video" demo:https://x86dc.wordpress.com/Which is a pretty awesome bit of design, I must say.Now, PIC sucks for not having registers -- but if you're going at 16 MIPS anyway, and that includes memory read/write at no cost, then it might not be too bad. In fact the faster RAM access would be to your advantage, though still limited by however much RAM there is inside.Possible methods for loading entire pictures at a time, for either platform, might include "streaming" (continuous SPI?) from external memory, and buffering that onboard -- even going so far as to write onboard Flash so the data can be stored as instructions, if necessary. It would be slow, and it would thrash the ROM, but such drastic methods are hardly beyond the realm of the "demo" -- hiding load times (from slow peripherals such as cassettes, floppies or hard disks) has always been part of the challenge.And again, not that you're *trying* to make an entire demo or anything... but the inner nuts-and-bolts are what count here, and I find that fascinating.QuoteThat's what I meant by "a little logic" -- you might double-buffer it yourself. It would of course be advantageous to use full port widths, too -- all you'd need is the functional opposite of a 74HC595: a latched parallel-loading register with serial out!For working with SPI, there may be an existing 1-bit FIFO/synchronizer part that can simply be added on; clock it with the video clock, keep feeding it data, and boom, your SPI's blank pulse disappears.Quote from: npelov on May 23, 2015, 04:20:13 pmHeh heh... at least you know your ears are still working!....for now...That, or the FBT. Probably more likely to succeed by adding acoustic damping foam inside the case, if you can.Tim

author: npelov
author_rank: Frequent Contributor
timestamp: May 23, 2015, 08:37:42 pm
content: Yes, technically AVR can do up to 256 pixels on X, but you need 9 MHz instruction cycle at least. That's (let's round it) 20 MHz clock. I knew 6 MHz is too low, no matter how many tricks you have in your sleeve. I'm not sure what's left - 10 us? - can't find proper specification of CGA border and retrace. But in theory you could load 32 bytes for 100 cycles.I'll probably get to AVR some day, but it requires time. Every MCU has it's good and bad sides. It'll probably cost me less time to get a 16 bit PIC and try it (because it has 16x16 bits work registers) - I already have 80% of the knowledge and development tools. But 256 pixels by 200 rows will not result square pixels. I need 320. Technically I can put two rows together and have 160x120, but that's ugly.I still want to use ISA card. What's holding me back for now is soldering 60 pin connector to 5-6 latch registers. That's a ton of cables. Might be cheaper to just draw and order a two layer PCB.One thing you mentioned got my attention. Making a continuous SPI. I didn't fully understand what you said, but I'll read it few times and try to put it together in my mind. I have to think about how to make it latch in the right moment - every 8 clock cycles. 74HC165 is the one (or one of them) you were looking for - parallel in, serial out, but I need 3 bit counter to divide the serial clock by 8 in order to latch with no gap. And yes, I'm not sure what I can do with RAM. Some PICs have parallel streaming port with support of external ram built in. You can access external ram as you access the internal with the difference that you also have it on a bus where you can latch a shift register like 74HC165 from... give me enough time and money ...Also can you explain more about 1 bit FIFO?How will it help to close the gap? And how do you implement it?Some time ago I stumbled upon dual access ram. You can access it from two places at the same time. So you can read and write at the same time. You can write next row as previous is being sent. However I don't remember where I've seen this ram. It was made in quite small volumes - like 1k or something. Not sure if I can get 16k and buffer a full frame.And the XT is not full speed video. It's interlaced and you can't see fast movements very well. It's similar to TV, but I think they have more iterations than even/odd. So it's equivalent to having slower frame rate - you still don't have full 25 frames/s information. But for slower videos missing information is less noticeable. And I agree it's cool

author: T3sl4co1l
author_rank: Super Contributor
timestamp: May 23, 2015, 10:56:22 pm
content: Quote from: npelov on May 23, 2015, 08:37:42 pmWhat's CGA pixel clock? Over 3.8MHz, at least (at 320 pixels). So yeah, you need more clock, so what? Double would seem to be quite achievable, at least for single cycle ISAs like AVR. And anyway, with MCUs in this class generally offering 16 to 32MHz (~= MIPS) operation, you have no reason or need to limit your clock rate, and with the extra cycles available, reading from a RAM/ROM buffer becomes a delicious prospect.Writing it in C, probably not, but that's pretty obvious for anything the least bit time-critical.16 bit PIC is probably comparable or even better in performance. Stretching that to 320 width and more lines shouldn't be too big of a deal. Sheer bit-banging is still met with the same serialized restriction (you might as well go with an overclocked, sequential, one-bit architecture!), but you have more capability to organize and ready data until it gets shifted out, so that still helps.Knowing your hardware intimately is the biggest help. Even on the 8-bit PICs, you can probably manage much better. Example: pump a page of RAM into the output port (maybe something like, read RAM into W, increment pointer, output W to port, shift W, output port again, etc.), then shift the page for the next line and so on. If possible, generate new lines in the background somehow (or change them progressively, or..).I only know little about old PIC, so I can't be of much help there. But figuring it out is half the fun, anyway.BTW, what do you need square pixels for? Off-square is just a transformation away. It's not a bug, it's a feature! Use it to your advantage. A power-of-2 screen width is nice for computing graphs, for example.QuoteBlah, whine whine whineJust be thankful you aren't wire-wrapping a thousand at once -- and having to patch the one wire that's buried under it all!http://www.futurlec.com/Protoboards.shtml#ISABUSBRD.shtml# ISABUSBRDIt looks like they're still around, or you might be able to find an edge connector to ribbon cable adapter.They also have a PCI proto board (through hole), which is... kind of scary...QuoteEh, I shouldn't have phrased it that way; more specifically, a one-bit wide channel with N bits of FIFO length. Clock bits in one end and out the other.It goes between clock domains, so it needs to have dual clocking capability. It doesn't need to be a synchronizing register as such. It probably needs to be more than that.One possible realization (not necessarily optimal, in terms of gates, or chips, or..) would be:Input: SCK in, MOSI inOutput: SCK in, MOSI outInput SCK clocks a counter. It might be a simple synchronous binary counter, N bits. It selects a one-of-2^N decoder, which feeds the clock input of 2^N type-D flip-flops. All the flip-flops have D = MOSI in.Output SCK clocks a counter. Same idea. It selects a 1-of-2^N mux, which selects one of the flip-flop outputs, which goes to MOSI out.The counters also have master resets tied to a secondary pin.At the beginning of a line, you strobe RST. So RST might simply be horizontal retrace. The pixel clock is independent of CPU clock, and starts advancing the output address. Right away, it's reading gibberish (actually, previous FIFO contents, in a circular loop -- since the counter overflows on its own), but that's fine because we're in retrace. Once bytes are readied and SPI starts spitting things out, sooner or later it'll connect and be on its way.You need well defined software delays to begin delivering data to this buffer, but the SPI clock can be as fast as possible and it doesn't matter, it doesn't need to be synchronized to the data. And you have much more leeway for timing between bytes.You would have to re-time the horizontal retrace signal to the video clock domain, otherwise you'll end up with dot crawl or something like that. Keeping the processor harmonically locked to the pixel clock would also be desirable. But that's fine, nothing a PLL can't do.The largest example of such an architecture would be, dual-port RAM the size of the frame buffer itself, in which case no refresh is even needed, you can just let the FIFO loop around and there's your frame. And the input address can then be random-access, because it's no longer having to stream an entire frame at once.QuoteI have a few chips laying around, I believe enough to do something like this. I kind of don't care enough to put such a thing together, though... I already have the original hardware in my three PCs, so what good is it?QuoteThe demos isn't full speed, in the sense of full frame updates, but then: what can really be said to be full, anyway?Zerovideo transmitted today (over any useful distance), whether by wire or through air, over the internet or via specific digital means, is uncompressed -- and all compressed video necessarily suffers from that type of artifact. How much so is a matter of degree and bitrate, nothing else. The most important sense of "full speed" is that,somethingis happening, each and every frame, and the visual illusion is largely maintained. Complaining that it's not updating the entire frame, every frame (as if to spite the video RAM that we somehow don't need it anymore!), is a dumb complaint, just as dumb as using a handheld calculator to crank every cell of a spreadsheet when you could write it out in Excel instead. Work smarter, not harder! Do more with less (hardware and time, that is)!Tim

author: miguelvp
author_rank: Super Contributor
timestamp: May 24, 2015, 03:16:41 am
content: CGA has a 14.32MHz pixel clock, actually 315/22 MHz (4 x 3.579545 MHz)Edit: that is for the 640x200 mode, half that for the 320x200 one: 7.16MHz (315/44)MHz (2 x 3.579545 MHz)HSync (Vertical refresh) is 15.75KHzactually 15751.575157515751575157515751575 so I will annotate it as 15751.(5751) the values in parenthesis is the periodic value that will repeat ad-infinitumVSynch (Screen refresh rate) is 60 Hz (Actually 59.94Hz)I guess you can derive the front and back porches for both horizontal and vertical.Say CGA 640x200 mode, it has to draw 640 pixels in 1/15.75KHz time, that would be 640 x 15.75KHz = 10.080MHz but we know the pixel clock is higher so how many pixels do you need to push including front porch. back porch and HSync?((315/22)*1000000)/15750 = ~909 pixels. Subtract 640 visible pixels and you get 269 pixels that are not displayed that encompass the front porch the sync pulse and the back porch, on VGA 640x480 @ 60Hz those values are:Code:Scanline part Pixels Time Visible area 640 25.422045680238Front porch 16 0.63555114200596Sync pulse 96 3.8133068520357Back porch 48 1.9066534260179Whole line800 31.777557100298Here is an image for VGA 640x480 @ 60Hz signals:So for CGA 640x200@60Hz the horizontal timing should be:Code:Horizontal timing:Scanline part Pixels Time Visible area 640 44.(698412)Front porch 27 1.8(857142)Sync pulse 161 11.2(4)Back porch 81 5.65(714285)Whole line909 63.4(857142)Then again this should be divisible by 2 so for the 320x200 mode I would choose:visible 320 pixelsfront porch 14 pixelssync pulse 80 pixelsback porch 40 pixelswhole line 454 pixelsThe pixel clock for 320x200 is 7.16MHz (315/44)The vertical timing is strange because it seems it's giving me 262.5 lines per frame so I think it's 263 lines and the frequency is really 59.94Hz200 of those are visibleSo this is the vertical timing for both the 320x200 @ 60Hz and for 640x200 also @ 60Hz (well 59.94Hz)Code:Vertical timing:Scanline part Pixels Time Visible area 200 12.68695818759190115337136883398Front porch 14 0.88808707313143308073599581837858Sync pulse 3 0.1903043728138785173005705325097Back porch 46 2.9180003831461372652754148318153Whole frame 263 16.683350016683350016683350016683But I did a lot of calculations so I might be way off or missed something.Timing sources:https://pineight.com/mw/index.php?title=Dot_clock_rateshttps://en.wikipedia.org/wiki/Crystal_oscillator_frequenciesImage source:http://www.xess.com/blog/vga-the-rest-of-the-story/VGA timings:http://tinyvga.com/vga-timing/640x480@60HzEdit: CGA modes in wiki page:http://en.wikipedia.org/wiki/Color_Graphics_AdapterAlso, maybe you can find a modeline for X-Windows for CGA monitors

author: miguelvp
author_rank: Super Contributor
timestamp: May 24, 2015, 04:43:36 am
content: More resources:CGA manual, with programming values for the MC6845http://www.minuszerodegrees.net/oa/OA%20-%20IBM%20Color%20Graphics%20Monitor%20Adapter%20(CGA).pdfCRT Controller chip Motorola MC6845http://www.classiccmp.org/dunfield/r/6845.pdfWith those two you probably can derive the actual timings instead of using my guessed ones.

author: T3sl4co1l
author_rank: Super Contributor
timestamp: May 24, 2015, 05:00:36 am
content: Ah yes, CGA was based on NTSC, for reasons probably obvious at the time. So oddball figures like the colorburst frequency and 59.94Hz are quite natural starting points.So an AVR at 14.32MHz would probably do a fine job, however you'll probably run out of data after 200-odd bits as well.Other possibilities: letterboxing (just throw away the extra; so what if it's "320 x 200", you only get to use the 256 in the middle!), sidebars of very different and simpler contents (say, live graphics in the "viewport", text or buttons on the side?), stuff like that.Tim

author: miguelvp
author_rank: Super Contributor
timestamp: May 24, 2015, 06:46:04 am
content: For those frequencies a PSoC 5LP or a PSoC 4 might do it all in one single chip as a frame buffer, of course using some external oscillator.The PSoC5LP might be better because it can do DMA and it also can be made into a USB device, or use the SPI component or CAN etc.

author: miguelvp
author_rank: Super Contributor
timestamp: May 24, 2015, 08:47:13 am
content: One more thing.It seems the monitor itself will process the colors since the input signals are TTL level. Maybe you can hack the monitor to allow direct analog inputs for RGB, apparently the monitor would process the TTL level using the following formula to drive the analog signals between 0.0V to 1.0VCode:red := 2/3×(colorNumber & 4)/4 + 1/3×(colorNumber & 8)/8green := 2/3×(colorNumber & 2)/2 + 1/3×(colorNumber & 8)/8blue := 2/3×(colorNumber & 1)/1 + 1/3×(colorNumber & 8)/8where color number ranges from 0 to 15, with the exception of colorNumber 6 that was treated differently (seems the just shifted the green to the right from hex AA to hex 55 to produce brown.source:http://en.wikipedia.org/wiki/Color_Graphics_Adapter#With_an_RGBI_monitor

author: npelov
author_rank: Frequent Contributor
timestamp: May 24, 2015, 09:14:36 am
content: Thanks for the resources. The processor on my card is 6845, so it'll be useful if I try to drive the card directly. From the first document:QuoteSo, you don't need dual port memory to have dual port implementation. Memory on my card is two chips of TMS4416-15NL - 16kx4 bit DRAM - not a dual port type.Quote from: miguelvp on May 24, 2015, 08:47:13 amI probably could, but I'm actually trying to reduce the number of colors to be able to catch up with speed - I tied the 4 inputs together to get 1 bit color. To drive it with full range of colors (or green shades in my case) would require more speed, ram ... everything. I would be happy if I get 320x240x1bit display.

author: npelov
author_rank: Frequent Contributor
timestamp: May 24, 2015, 11:08:10 am
content: I don't understand few things on this page:http://pinouts.ru/Slots/isa_pinout.shtmlIn the table I see two clocks:B20 CLOCK ---> System Clock (67 ns, 8-8.33 MHz, 50% duty cycle)B30 OSC ---> High-speed Clock (70 ns, 14.31818 MHz, 50% duty cycle)So they are both 50% duty cycle. Then where in this table is this clock:BCLKBus Clock, 33% Duty Cycle. Frequency Varies. 4.77 to 8 MHz typical. 8.3 MHz is specified as the maximum, but many systems allow this clock to be set to 12 MHz and higher.I don't see any 33% clock.So let's say that B20 is the BCLK signal. Is it 33% or 50% duty?

author: T3sl4co1l
author_rank: Super Contributor
timestamp: May 24, 2015, 02:44:11 pm
content: This doesn't say anything about duty cycle,http://users.ece.gatech.edu/~hamblen/489X/ISA.htmTim

author: amyk
author_rank: Super Contributor
timestamp: May 25, 2015, 01:52:25 pm
content: The MCU you're using should be able to make a 40x25 framebuffer display at 320x200 resolution with an 8x8 font. Store the font in program ROM and the framebuffer in RAM. Do the font lookup during the horizontal retrace and receive processing during vertical retrace. Forget about hardware SPI, just bit-bang the port directly.

author: npelov
author_rank: Frequent Contributor
timestamp: June 18, 2015, 01:28:34 pm
content: I haven't got enough time to play with the monitor, but I just found out that PIC18FxxJ11 has SPI DMA function. It can send portion of ram through SPI without interruption. How cool is that - low end MCU with dma support! It can also be used for RAM-RAM copy operations in the background by just assigning SPI data in and out to the same MCU pin. When I have time I'll do some experiments with it.

author: McBryce
author_rank: Super Contributor
timestamp: June 18, 2015, 01:54:14 pm
content: Why not just buy yourself a cheap Retro laptop with a CGA port. Something like an Epson Equity LT, or one of the early Toshibas? They go for peanuts on ebay. You could use the RS232 port to get it to communicate with some test equipment or something equally cool.McBryce.

author: rr100
author_rank: Frequent Contributor
timestamp: June 18, 2015, 02:29:59 pm
content: I remember the times when Icouldn't afford even a CGA monitor! So I've got a CGA card with the composite/analog output and planned to use a modulator from a Spectrum Z80 clone to use a TV as monitor. I never got to finish the project but I think I might have both the board and the modulator somewhere...

author: P K
author_rank: Newbie
timestamp: June 19, 2015, 04:51:53 am
content: QuoteHow fast can you toggle GPIOs with the PIC? I did a disgusting, dirty hack to get 640x480x3bpp out of an AVR without overclocking it:http://dqydj.net/how-to-produce-640x480-vga-color-video-from-an-arduino/(It looks bad because it's 32 MHz logic driving 25.175 MHz - but I only did it for the laughs. You could clean it up pretty easily.)Anyway, you could do it a better way. I got a clock out of my AVR, then doubled it using delay & XOR. You could, of course, use a PLL... or, better, run your uC at the pixel clock of CGA (or 2x).8 bit microcontrollers can write out 8 bits per cycle, so I wrote out 8 bits, then my doubled clock was the select input to a 74F257N. The result of that is your 8 bits driving 4 bits per pixel at 2x the speed.

author: miguelvp
author_rank: Super Contributor
timestamp: June 19, 2015, 08:59:49 am
content: I think this $10 PSoC 5LP prototype board should be able to deal with the video signal generation for 640x480@60Hz but it doesn't have enough memory for a VGA frame buffer, but for CGA it should be plenty:http://www.cypress.com/?rid=108038Combined with this $5 3 bit per color R2R DAC module:http://www.wvshare.com/product/VGA-PS2-Board.htmThe PSoC 5LP chip that comes on the prototype board only has 64K of SRAM so it could only hold one frame at 320x200 RRRGGGBB, so it can only update the frame buffer during the VSync.But we are talking CGA here so it only needs 4 bits per color and use a palette (pretty much a LUT that provides the 16 CGA colors), that would give the double buffer.I don't see it having any trouble doing the other CGA modes either (even the 640x200 2 color mode).It does have 24 DMA channels so maybe one could use an external frame buffer if more than CGA was needed.It also has a four 8 bit DACs so I guess I wouldn't need the external R2R DAC but I doubt it could reach the ~7.16MHz pixel clock needed.Of course it should be able to do SPI, CAN, I2C, and even RS232. and let's not forget USB full-speed of course.I do have all the parts, other than I don't know if any of my displays will lock at CGA resolution so maybe I give it a play during the weekend, it should be a fun weekend project.Edit: If I don't find a CGA capable monitor at least I could look at the signals on my scope, or better yet, use one of my analog scopes in XY mode to display the output in monochrome. I could use my diligent analog discovery to provide the sweep but I would need to build something like w2aew did to display NTSC on his scope.

author: npelov
author_rank: Frequent Contributor
timestamp: June 19, 2015, 04:53:45 pm
content: Quote from: McBryce on June 18, 2015, 01:54:14 pmBecause it's boring. And also because it'll drain another 100W of power and take up space. (The monitor consumes the same power as a modern LCD display - I measured it)Also they sell for quite a lot of peanutsIBM PC/AT x286 Computer. I tried local search - no one is giving these cheaply.Quote from: rr100 on June 18, 2015, 02:29:59 pmI remember the time my parents bought me a 16 bit, 12 MHz x86 (NEC V20) PC. Then I messed up something and my father took the monitor for punishment. I found somewhere how to connect the CGA out to composite in on my TV and I played games and programmed in pascal.Quote from: P K on June 19, 2015, 04:51:53 amI have the feeling you are cheating a bit too much. Are you sure you can you render full 640x480 image? Let's say you have the memory for it. The color patterns seam repeating - you can easily load the 32 work registers and output them 10 times to achieve 640 pixels row, but that's not actually 640 pixels. It's 64 pixels repeated 10 times. I'm not sure what you are doing with the text. Maybe you are switching to 1 bit per pixel and output 32x8 = 256 pixels, then output black.If I'm wrong and you can really output 640 different pixels for each row I'll study atmel MCUs a bit. But I still can't believe it.Quote from: miguelvp on June 19, 2015, 08:59:49 amI believe you. However every new architecture requires time to study it. I've never had to deal with ARM. I might spend that time some day, but it would be for better reason. I don't have enough time for playing with unknown to me architecture for not-serious purpose . I remember it took me whole day to make a simple 128x64 LCD display work. I'm really curious about these PSoC, but I need to have an excuse (serious reason) to check it out. And I will do it some day. A problem with these would be that it comes in a dirty little package, that's hard to solder and you have to stick with the prototype kit. The prototype kit is limited to it's schematic. For example I didn't see an quartz crystal. So if you want to put your own crystal might be a little tricky. There might be other limitations of the kit. That's why I prefer to use my own design rather than a board (like arduino). Sometimes you can replace the 16 MHz crystal with a 14 MHz one, but sometimes board limits you. But it's nice for quick and dirty "Proof of concept".

author: mikerj
author_rank: Super Contributor
timestamp: June 19, 2015, 05:07:58 pm
content: Quote from: miguelvp on May 24, 2015, 08:47:13 amThis is exactly what I did many (many, many) years ago when I couldn't afford a VGA monitor for my 286. I remember having to buffer and amplify the RGB signals from the VGA card with a trio of simple two transistor amps to get acceptable brightness and contrast

author: miguelvp
author_rank: Super Contributor
timestamp: June 19, 2015, 05:57:25 pm
content: Quote from: npelov on June 19, 2015, 04:53:45 pmThe nice thing about the PSoC is that it can drive the video output by hardware.So you setup a DMA to transfer the current line of pixels via a latch and the horizontal/vertical sync is all done with PWMs with no software pushing the pixels.The DMA will generate an interrupt to fetch the next line of the frame buffer using the vertical counter of the PWM, it should be quite fast at doing this, and ARM well it's really just C, so other than learning how to setup all the custom hardware you can define in the PSoC it's easy from.Since you are using CGA you don't need the DAC just the 4 bits, so the board by itself will do. But for me since I want to do a proof of concept I'll use the DAC. I will setup a LUT to translate the 4 bits to the right RGB value and only implement the 320x200 mode for now.As for your question to P K about how he is displaying text, well you just need an array with the character sprites and use an index, so the frame buffer doesn't need to be pixel addressable, you just have a byte that is the index and that will fill the 8x8 (or whatever the size of the character is)So a 80x60 (4800 bytes) frame buffer will display 640x480, add another 80x60 buffer to describe the foreground and background color per character, like the first nibble (4bits) describes the foreground color and the 2nd nibble is the background color, and that's it. You get a 640x480 display using only 9600 bytes with two colors per 8x8 cell.Edit2: also you can use the most significant bit of the character frame buffer to indicate if the character is blinking or not, that still leaves you 127 entries and some could be control characters as well, like what old terminals used.Edit: as for the XTal, the leads are short enough that you could still use one, or use an external OCXO that drives the clock. But the clock should be accurate enough to do CGA so there is no need for that, we will see, I'll play with it this evening after work and hopefully I'll get something done tonight or maybe tomorrow.

author: P K
author_rank: Newbie
timestamp: June 20, 2015, 06:07:43 pm
content: Quote from: miguelvp on June 19, 2015, 05:57:25 pmPretty much this - I just have everything hardcoded in Flash instead of a LUT (it's embedded in the program for the demo.) If I were to develop it further I would do a full font lookup table.Of course, architecture doesn't really matter: If you want to go down this path, all you need is to be able to output 8 bits in a single clock - I don't know PIC, but there has to be a write to a Latch or Port which completes in parallel. If you can get your code putting out 8 bits simultaneously, let me know and I'll help you with the second part.My article is using a bit of subterfuge - 16 MHz may be the part's speed, but throughput is actually what matters here. 16 MHz x 8 bits was 128 Mb a second, plenty of data for VGA (and/or CGA). Similar math applies to the PIC.

author: miguelvp
author_rank: Super Contributor
timestamp: June 20, 2015, 08:16:06 pm
content: Yesterday didn't have much time to play with this because my kids are visiting for fathers day. But I took advantage that they wake up late and got an 80 by 60 array each of them displaying an 8x8 pixel single color block and locked at 640x480@60Hz (well the OSD reports 59Hz) but I'm using the timings in here:http://tinyvga.com/vga-timing/640x480@60HzIt does seem to loose lock after some minutes but then it locks right away, but this is just the first pass to make sure the PSoC 5LP prototype module is outputting the right signals to the R2R DAC.Edit: seems the lock stabilized because it hasn't lost it for the last 30 minutes.The DAC has 3 bits per color but I'm only using the upper 2 per color so it could go brighter if I tie the unused bit to the less significant bit per color. But I guess I can do an RRRGGGBB since each DMA transfer is actually transferring a full byte.Here is the output on my wine-box monitor that I use for this kind of projects:Link to the wine box monitor construction (not too exciting I'm afraid):https://www.eevblog.com/forum/microcontrollers/tft-lcd-for-raspberry-pi-b/msg606242/#msg606242The PSoC 5LP prototype kit and the VGA R2R DAC module:I'll try to see if I can get the display to do 320x200, then I can make it so it does output TTL as the CGA monitor will expect, but I'll add a LUT out of that output so it can generate signals needed for the R2R DAC (kind of having the CGA LUT built-in to simulate what the CGA monitor will do to produce the analog signals to the CRT). I will use the values this wiki page has:https://en.wikipedia.org/wiki/Color_Graphics_Adapter#With_an_RGBI_monitor

author: miguelvp
author_rank: Super Contributor
timestamp: June 20, 2015, 09:24:39 pm
content: Also, if you noticed, it has a micro USB on board, and this can be used as a USB device to interface with any USB host as well as it can power the board.The kit also has plenty of EPROM to store the character sprites so it could be made so it's a full CGA controller card that supports all the CGA modes and probably expand a bit on that.

author: miguelvp
author_rank: Super Contributor
timestamp: June 21, 2015, 03:00:12 am
content: Had some more time so I did clean up the signals and timings, but I'm still at 640x480 mode.I did however increased the colors to 8 bits (RRRGGGBB and replicated the less significant blue to B0 on the DAC)Also I increased the frame buffer to 80x240 so the blocks are 8x2 each.This image has red green blue black and white, just to check if the colors come out fine and also to check for any jitter which I found none.Looks like resizing the picture from my tablet added some artifacts, but they are not on the actual display.Edit:This code shows all the individual addressable 8x2 blocks, by making an RGB pattern horizontally and vertically.Code:switch (y%3){case 0:switch (x%3){case 0:frame = RED;break;case 1:frame = GREEN;break;default:frame = BLUE;break;}break;case 1:switch (x%3){case 0:frame = GREEN;break;case 1:frame = BLUE;break;default:frame = RED;break;}break;default:switch (x%3){case 0:frame = BLUE;break;case 1:frame = RED;break;default:frame = GREEN;break;}break;}I used my computer to resize the image to 800x600 so it doesn't do those artifacts:This is a closeup of the pattern:

author: miguelvp
author_rank: Super Contributor
timestamp: June 21, 2015, 10:56:52 am
content: So I had more time this morning, the bad news is that I can't get my monitor to lock at 320x200 or 640x200 or anything that uses a very slow clock.I do expect that these values reflect the true CGA but I can't get a lock nor I do have a monitor that can do this resolution (yeah I could use the scope on xy mode but it will be monochrome)Real CGA?refresh rate 64.436 Hzvertical refresh 15.980 kHzPixel freq 7.1590909090909090909090909090909 MHzVisible area 320Front porch 8Sync pulse 80Back porch 40Whole line 448Visible area 200Front porch 6Sync pulse 18Back porch 24Whole frame 248But I was able to make it lock at 640x400@70Hz using the timings here:http://tinyvga.com/vga-timing/640x400@70HzBecause the DMA handles a byte at a time I had to add more digital logic to the PSoC to split a byte into two 4 bits pixels and so far I can do 160x200 with 16 CGA colors:Closeup:The digital programmable blocks on the PSoC 5LP are getting a bit complicated but it's nice that the programmable digital blocks can take care of doing all the video timings and the LUT to convert the CGA values into VGA.I really don't know of any other chip (unless is one of the newer FPGA_SoC chips) that can do this in such a somewhat inexpensive chip.The actual code other than setting up the digital modules and dealing with the scanline interrupt to do a frame buffer refresh is really not doing much, so there is plenty of processing power left on the ARM Cortex M3Here is the current iteration of the digital block schematic:All of this is implemented on the chip, no external components btw. And yeah, the DMA and the interrupt are mirrored so I could fit them there, I usually like the interrupt signal on the right of the DMA transfer so it's more readable.Edit: if you look at the top multiplexer you can see i'm splitting the nibbles using a 2 bit counter, I could change the divider on the CGA_CLK to 2 and cycle between [1:0],[3:2],[5:4] & [7:6] to do 320x200 with 4 colors per pixel.Also I could add one more bit to the counter and do 640x200 with 2 colors per pixel. The LUT even if it's done in hardware it can also be configured on the fly by software so I could add the CGA palettes, actually all of the digital blocks can be configured on the fly so the ARM processor could implement all the needed CGA modes and palettes.The code I used to fill in the pattern in nibbles is:Code:index = (x*2+y)%16;frame = index|(index+1)<<4;The hardware blocks take care of the restEdit2:Here are the resources used/freeCode:------------------------------------------------------------Technology mapping summary------------------------------------------------------------Resource Type : Used : Free : Max : % Used============================================================Digital clock dividers : 2 : 6 : 8 : 25.00%Analog clock dividers : 0 : 4 : 4 : 0.00%Pins : 13 : 35 : 48 : 27.08%UDB Macrocells : 32 : 160 : 192 : 16.67%UDB Unique Pterms : 42 : 342 : 384 : 10.94%UDB Total Pterms : 51 : : :UDB Datapath Cells : 5 : 19 : 24 : 20.83%UDB Status Cells : 0 : 24 : 24 : 0.00%UDB Control Cells : 5 : 19 : 24 : 20.83%Control Registers : 5DMA Channels : 1 : 23 : 24 : 4.17%Interrupts : 1 : 31 : 32 : 3.13%DSM Fixed Blocks : 0 : 1 : 1 : 0.00%VIDAC Fixed Blocks : 0 : 4 : 4 : 0.00%SC Fixed Blocks : 0 : 4 : 4 : 0.00%Comparator Fixed Blocks : 0 : 4 : 4 : 0.00%Opamp Fixed Blocks : 0 : 4 : 4 : 0.00%CapSense Buffers : 0 : 2 : 2 : 0.00%CAN Fixed Blocks : 0 : 1 : 1 : 0.00%Decimator Fixed Blocks : 0 : 1 : 1 : 0.00%I2C Fixed Blocks : 0 : 1 : 1 : 0.00%Timer Fixed Blocks : 0 : 4 : 4 : 0.00%DFB Fixed Blocks : 0 : 1 : 1 : 0.00%USB Fixed Blocks : 0 : 1 : 1 : 0.00%LCD Fixed Blocks : 0 : 1 : 1 : 0.00%EMIF Fixed Blocks : 0 : 1 : 1 : 0.00%LPF Fixed Blocks : 0 : 2 : 2 : 0.00%SAR Fixed Blocks : 0 : 2 : 2 : 0.00%------------------------------------------------------------PLD Packing Summary------------------------------------------------------------Resource Type : Used : Free : Max : % Used====================================================PLDs : 12 : 36 : 48 : 25.00%Flash used: 21248 of 262144 bytes (8.1 %).SRAM used: 36437 of 65536 bytes (55.6 %). Stack: 8192 bytes. Heap: 4096 bytes.So I still have plenty of resources and even SRAM.

author: miguelvp
author_rank: Super Contributor
timestamp: June 21, 2015, 10:31:53 pm
content: I doubled the clock and reduce the colors to just 4, using CGAs Palette 3 (black, cyan, red, white) and I got 320x200.Here is a close up:I'll do a 640x200 next maybe just blue and white like some terminals used to use.

author: miguelvp
author_rank: Super Contributor
timestamp: June 22, 2015, 12:40:32 am
content: Well I got to 640x200 but had to bypass the LUT because its causing me some timing issues and it would not display the colors that I wanted.Even without the LUT the image is not stable if I put a high frequency pattern in just black and white. It doesn't loose lock but I see some noise in the image.I guess I could reroute signals in the fabric to meet the needed timings.I'm running the master clock at 24MHz that gives me 25.500MHz instead of the asked 25.125MHz so I guess I should use an external oscillator with better precision if I want to go this high and with a lot of switch on/off.VSynch fall time is ~6ns, rise time ~30nsThe video going on/off per pixel makes the rgb signal to have a rise and fall time of ~15.5nsStill I think it can be tweaked to get it more stable, but I think 640 is about the maximum I can get out of this PSoC. I would use the higher frequencies (up to 80MHz) but the PLL only operates with an input between 1MHz to 48MHz. When selecting 48MHz with the built in oscillator I get 24MHz out, I still can make the monitor lock and it runs without so much noise but I still have to bypass the LUT.Well I did increase the PLL output to ask for 50.350 MHz and using the internal IMO at 48MHz it's giving me 51.000MHz so I can half that and get 25.5MHz. Running the IMO at 24MHz and asking for 50.350 it gives me 50.400 MHz so I'll end upt with 25.200 which is pretty close. The maximum output of the PLL is 80MHz, maybe I can ask for triple (75.525) but oh well, I think there are still ways to get the 640x200 stable.Or use a D-FlipFlop to half the frequency, or use one of the many modules they have, so I haven't given up but this might require more work, but if 640x200 with two colors is not that important it can do the rest with no problems.

author: ranch varment
author_rank: Regular Contributor
timestamp: June 22, 2015, 06:23:37 am
content: Thats so cool, I didnt know monitors had an extension on their input to communicate with pixel blocks?

author: miguelvp
author_rank: Super Contributor
timestamp: June 22, 2015, 04:42:08 pm
content: Quote from: ranch varment on June 22, 2015, 06:23:37 amNot quite but close enough, it's just a serialization of data controlled by horizontal and vertical syncs. But the "communication" is unidirectional, as in output from the video controller to the display.The monitor uses the horizontal sync to determine the raster speed from left to right, on old analog CRTs that will directly drive the horizontal deflector to sweep the electron beam left to right.The vertical sync does the same but for the Vertical deflection coil that determines the y deflection over time. Also when on a retrace the electron gun is off during the sync pulse. The intensity of the beam is controlled by the analog voltage per color component (between 0-0.7V, with a 75 Ohm termination).Even modern HDMI uses the same raster serialization but it's control via the data channels so It's a bit more complicated with modern monitors but in essence it's still the same.

author: miguelvp
author_rank: Super Contributor
timestamp: June 23, 2015, 02:55:46 pm
content: Got the timings figured out and added the CGA 2K sprites:I'm skipping every other line so it's not too busy, also I added a space in between characters for the same reason.The image is very stable but I want to up the MASTER_CLOCK to 75MHz, right now I'm dividing it to get the needed 25MHz but I could use a frequency divider on the hardware digital blocks and still keep the 75MHz for the BUS_CLK (CPU)Next step is to put everything together with all the modes, palettes, etc and last but not least the communication protocol over the USB device, maybe I just leave it as RS232 since I could use a USBUART module within the chip.Also a friend of mine might have a CGA so I can try to make it work on CGA instead of VGA. Or just support both

author: miguelvp
author_rank: Super Contributor
timestamp: June 25, 2015, 05:59:31 pm
content: Still no CGA monitor, but got some progress done last night on colors and text, 16 colors 80x25 characters, with the full CGA 8x8 character font loaded on the PSoCs 2KB EEPROMNo flickering at all and very stable. Pixel resolution is 640x200 for the actual pixel frame buffer.I'm copying from the EEPROM to the frame buffer based on a 80x25 text buffer, and using another smaller buffer to store the colors per character cell.

author: miguelvp
author_rank: Super Contributor
timestamp: June 26, 2015, 05:09:28 am
content: Now with background colors as well, not blink bit implemented yet.My color pixel clock is one pixel too early, I'll have to figure out how to delay the color by a pixel clock.My friend at work is going to lend me his monitor so I can check if my CGA timings work over the weekend.

author: miguelvp
author_rank: Super Contributor
timestamp: June 26, 2015, 07:07:32 am
content: So I guess last night I was playing with the colors on my VGA monitor set at 640x400 but displaying really 640x200. Not sure what I was doing but I found this screenshot of altering the 2nd scanline to do something else than the main scanline, since I have really two lines per line.Well I want this effect for other purposes so the old 15KHz games look like they would on an LCD.Granted that whatever I was doing made the black on black characters appear grey on the alternate lines, but I think this would be a cool effect so retro games could look like they did.It's a good thing I have perforce installed and I've been using it, so I can look at what I did. That is if I ever checked it in. but knowing it's possible to get this look on an LCD is good to know.

author: P K
author_rank: Newbie
timestamp: June 27, 2015, 06:47:02 pm
content: Excellent progress! Looking awesome!Those PSoC parts are interesting - I've got a bunch of the v4 PSoC dev boards, the $4 ones with the USB built onto the PCB. I've been playing with CPLD graphics lately, but it looks like you can do a lot of the logic directly on the PSoC - will have to break one out next and play with it.

author: miguelvp
author_rank: Super Contributor
timestamp: June 27, 2015, 07:11:59 pm
content: I would have gone for the PSoC 4 ones but they don't have DMA support on the specific chip they used for that board, I think they did introduce one chip (no devboard) that has at least one DMA channel but not sure.There might be ways to still transfer the data fast enough for lower resolutions.Edit:Link to the $4 PSoC 42xx prototyping chip (CY8C4245AXI-483) datasheet:http://www.cypress.com/?mpn=CY8C4245AXI-483It has enough PWMs to drive the HSync and VSync but not much more, no DMA, no EEPROM, not enough SRAM (4KB) and just 32KB of flash.Link to the $10 main PSoC 5LP prototyping chip (CY8C5888LTI-LP097) datasheet:http://www.cypress.com/?mpn=CY8C5888LTI-LP097It also has a 2nd 5LP (the programmer) with 11 GPIOs wired that could be used to drive the display. But then you can't program the other one, so you'll have to preserve the bootloader and bootloadable and I'm not sure if it can be programmed with the miniprog 3, but I guess if you have several 5LP prototype boards you could preserve a couple of the kitprog parts to restore the rest. Seems the SWDCLK and SWDIO are connected to the USB D- and D+ pins and XRES is available so you might be able to repurpose the kitprog part if you have many of them.Link to the 2nd PSoC 5LP (CY8C5868LTI-LP039) used to program the main one:http://www.cypress.com/?mpn=CY8C5868LTI-LP039Only difference is that the programming one can only reach 67MHz while the main one can do 80MHz.

author: miguelvp
author_rank: Super Contributor
timestamp: June 28, 2015, 03:21:36 am
content: Got more progress but in the meantime here is the 2K bitmap font as a 2048x8 pixel png 2 bit black and white.I had to convert it to.ras format so I could get the raw hex values, then I used a hex editor to convert the hex dump to text and then changed it to the .csv file needed to import the rom.My first attempt had some of the sprites offset, the original image I used showed several rows so I had to paste them to concatenate them. I guess I could have typed every hex number but that would have taken forever, and I couldn't find the actual rom or hexdump anywhere.So I'm also including the comma separated values file I used (just remove the .txt that I needed to add so I could attach it).

author: miguelvp
author_rank: Super Contributor
timestamp: June 28, 2015, 04:03:36 am
content: So my friend lent me his Sony Trinitron 13 inch monitor (KV-1311CR) that has RGBI input and actually will work in CGA mode.I derived the timings from the CGA manual I linked on page 2 or was it 3, the values there are in hex and character based so they have to be converted to decimal and multiplied by 8 and came out with this (for 640x200 @ 63.5Hz):Code:----------------------------------------------Screen refresh rate 63.5HzVertical refresh 15748 kHzPixel freq. 14.236192 MHzHorizontal timing (line)Polarity of horizontal sync pulse is negative.Scanline part Pixels Time Visible area 640 44.955842Front porch 80 5.619480Sync pulse 80 5.619480Back porch 104 7.305324Whole line 904 63.500127Vertical timing (frame)Polarity of vertical sync pulse is negative.Frame part Lines Time Visible area 200 12.700025Front porch 18 1.143002Sync pulse 6 0.381001Back porch 24 1.524003Whole frame 248 15.748031----------------------------------------------I did enabled the CGA component on the schematic and wired it on a breadboard.The pins right to left are: Red, Green, Blue, Intensity, HSync, VSync, Ground. All of them are TTL level (0V-5V).Edit: USB is just for power but that connector can be used to communicate with the PSoC 5LP as well, UART, SPI, I2C, HID and even MIDI.The VSync took a while to lock and I had to keep trying to adjust it, maybe the pulse is too big or not big enough, It doesn't help that the monitor takes about 2 minutes to even come on, so maybe it's because it has seen better days, but I'll keep on playing to see if I can make the VSync lock easier. At the moment if I move the VHold just a bit it starts rolling. Also the HSync front porch might need to be smaller because the image is too much to the right and using the "H Cent" on the monitor I couldn't getting totally centered.I'll have to play with the timings a bit, also I got the pixel clock to 14.222 MHz that's all the PLL would give me. which is close enough to the desired 14.236192 MHz I was aiming for.Then again maybe my timings are way off because that puts the display at 63.5Hz frame rate. But based on all the docs I could find it seems that should be the case.

author: miguelvp
author_rank: Super Contributor
timestamp: June 28, 2015, 04:05:28 am
content: One more with the lights off and closer:And a closeup:Edit: compare to the LCD one that doesn't translate pixel value 6 to brown and it shows as dark yellow on the LCD one. CGA did have a special value for color index 6 and this Trinitron seems to do the translation as well.Look for the number "1" second row, second column on the image below. 7th column 2nd row above.The banding (some lines look darker in the image) is interference from the 63.5 Hz and the camera, with my naked eyes there is no banding at all.Edit: while running it's in between 110 and 120 mW power consumption.

author: miguelvp
author_rank: Super Contributor
timestamp: June 29, 2015, 04:01:13 am
content: So I had to use my scope to adjust the front/back porches for both the horizontal and vertical. Since after fixing why it was hard to get the vertical hold working (I had to keep on sending HSyncs during a VSync and I wasn't). Well it was locking just fine but my screen ended up pushed to the lower right corner of the display.Meaning that my Front Porch was 0 both on the horizontal and vertical.First I adjusted the HSync pulse so it would reflect the CGA values I posted earlier. Chan 1 (yellow) is the red color and Chan 2 (blue) is the HSynch signal:Then took care of the VSync so the pulse will start where is supposed to start. You can see some noise on both HSync (blue) and VSync (yellow) that is caused when there is video output I guess I'm getting a bit of a crosstalk but that's fine because it helps me identify the front and back porch for the VSync pulse:Edit, the PSoC clock gen lies, it's telling me my pixel clock is 14.222333 MHz but the scope shows me that it's really 14.206061 MHz. All the annotations are done with the 14.222333 one that Creator was telling me what it was.Edit: (Ideal values are still the ones posted in post#60at the top of this page, the ones shown here is the closest the PSoC 5LP let me get to).Result, a happy CGA signal that is dead center in the monitor.Another closeup, I still have to fix why my color is one pixel too early or better, why are the characters one pixel late.

author: zero_budget_tech
author_rank: Newbie
timestamp: July 03, 2015, 11:53:05 pm
content: Nothing much to add, but I enjoyed reading this.Will probably go for a vector display myself, if I ever build the machine I have been thinking about. (8 bit, through hole, front panel input, probably z80)

author: miguelvp
author_rank: Super Contributor
timestamp: July 04, 2015, 12:14:01 am
content: Over the weekend I want to merge this project:http://www.element14.com/community/thread/24287/l/psoc-4-pioneer-kit-community-project17--2-channel-oscope-with-graphicslcdTo the CGA display making it a cheap 80KHz 2 channel scope. Might be able to push it to 160KHz but it's not going to be earth-shattering by any meansI'm planning to use the BNC adapter I have for my Diligent Analog Discovery to be able to hook the probes.http://www.digilentinc.com/Products/Detail.cfm?Prod=DISCOVERY-BNCI'll use the Diligent Analog Discovery as a function generator to find out where the -3dB falls into, so it might take me more than just the weekendEdit: It would be easier if I could rotate the yoke of the monitor or if I displayed the waves from up to down as the scanline draws the screen for a faster display update rate. But I guess I could use a comparator to know where to draw the current signal bypassing the frame buffer and leaving the signal display all handled by hardware as well, overlayed into the frame buffer.