Author Topic: Make use of an old CGA monitor  (Read 31966 times)

0 Members and 1 Guest are viewing this topic.

Offline npelovTopic starter

  • Frequent Contributor
  • **
  • Posts: 330
  • Country: bg
    • Microlab.info
Re: Make use of an old CGA monitor
« Reply #25 on: May 23, 2015, 08:37:42 pm »
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 :)
« Last Edit: May 23, 2015, 08:50:59 pm by npelov »
 

Online T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 21567
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: Make use of an old CGA monitor
« Reply #26 on: May 23, 2015, 10:56:22 pm »
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.

What'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.

Quote
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.

Blah, whine whine whine ;D  Just 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
# ISABUSBRD
It 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...

Quote
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?

Eh, 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 in
Output: SCK in, MOSI out
Input 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.

Quote
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.

I 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? :P

Quote
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 :)

The demos isn't full speed, in the sense of full frame updates, but then: what can really be said to be full, anyway?  Zero video 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, something is 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
Seven Transistor Labs, LLC
Electronic design, from concept to prototype.
Bringing a project to life?  Send me a message!
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: Make use of an old CGA monitor
« Reply #27 on: May 24, 2015, 03:16:41 am »
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.75KHz
actually 15751.575157515751575157515751575 so I will annotate it as 15751.(5751) the values in parenthesis is the periodic value that will repeat ad-infinitum
VSynch (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: [Select]
Scanline part     Pixels Time [µs]
Visible area      640    25.422045680238
Front porch       16     0.63555114200596
Sync pulse        96     3.8133068520357
Back porch        48     1.9066534260179
Whole line   800    31.777557100298

Here is an image for VGA 640x480 @ 60Hz signals:


So for CGA 640x200@60Hz the horizontal timing should be:
Code: [Select]
Horizontal timing:
Scanline part     Pixels Time [µs]
Visible area      640    44.(698412)
Front porch       27     1.8(857142)
Sync pulse        161    11.2(4)
Back porch        81     5.65(714285)
Whole line   909    63.4(857142)

Then again this should be divisible by 2 so for the 320x200 mode I would choose:
visible 320 pixels
front porch 14 pixels
sync pulse 80 pixels
back porch 40 pixels
whole line 454 pixels

The 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.94Hz

200 of those are visible

So this is the vertical timing for both the 320x200 @ 60Hz and for 640x200 also @ 60Hz (well 59.94Hz)

Code: [Select]
Vertical timing:
Scanline part   Pixels  Time [ms]
Visible area    200     12.68695818759190115337136883398
Front porch     14      0.88808707313143308073599581837858
Sync pulse      3       0.1903043728138785173005705325097
Back porch      46      2.9180003831461372652754148318153
Whole frame     263     16.683350016683350016683350016683

But 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_rates
https://en.wikipedia.org/wiki/Crystal_oscillator_frequencies

Image source:
http://www.xess.com/blog/vga-the-rest-of-the-story/

VGA timings:
http://tinyvga.com/vga-timing/640x480@60Hz

Edit: CGA modes in wiki page:
http://en.wikipedia.org/wiki/Color_Graphics_Adapter

Also, maybe you can find a modeline for X-Windows for CGA monitors
« Last Edit: May 24, 2015, 03:42:44 am by miguelvp »
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: Make use of an old CGA monitor
« Reply #28 on: May 24, 2015, 04:43:36 am »
More resources:

CGA manual, with programming values for the MC6845
http://www.minuszerodegrees.net/oa/OA%20-%20IBM%20Color%20Graphics%20Monitor%20Adapter%20(CGA).pdf

CRT Controller chip Motorola MC6845
http://www.classiccmp.org/dunfield/r/6845.pdf

With those two you probably can derive the actual timings instead of using my guessed ones.
 

Online T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 21567
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: Make use of an old CGA monitor
« Reply #29 on: May 24, 2015, 05:00:36 am »
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
Seven Transistor Labs, LLC
Electronic design, from concept to prototype.
Bringing a project to life?  Send me a message!
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: Make use of an old CGA monitor
« Reply #30 on: May 24, 2015, 06:46:04 am »
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.
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: Make use of an old CGA monitor
« Reply #31 on: May 24, 2015, 08:47:13 am »
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.0V

Code: [Select]
red   := 2/3×(colorNumber & 4)/4 + 1/3×(colorNumber & 8)/8
green := 2/3×(colorNumber & 2)/2 + 1/3×(colorNumber & 8)/8
blue  := 2/3×(colorNumber & 1)/1 + 1/3×(colorNumber & 8)/8
where 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
« Last Edit: May 24, 2015, 09:09:15 am by miguelvp »
 

Offline npelovTopic starter

  • Frequent Contributor
  • **
  • Posts: 330
  • Country: bg
    • Microlab.info
Re: Make use of an old CGA monitor
« Reply #32 on: May 24, 2015, 09:14:36 am »
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:

Quote
A dual-ported implementation allows the
processor and the graphics control unit access to this buffer.

So, 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.

Maybe you can hack the monitor to allow direct analog inputs for RGB

I 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.
 

Offline npelovTopic starter

  • Frequent Contributor
  • **
  • Posts: 330
  • Country: bg
    • Microlab.info
Re: Make use of an old CGA monitor
« Reply #33 on: May 24, 2015, 11:08:10 am »
I don't understand few things on this page:
http://pinouts.ru/Slots/isa_pinout.shtml

In 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:

BCLK
Bus 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?
 

Online T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 21567
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: Make use of an old CGA monitor
« Reply #34 on: May 24, 2015, 02:44:11 pm »
This doesn't say anything about duty cycle,
http://users.ece.gatech.edu/~hamblen/489X/ISA.htm

Tim
Seven Transistor Labs, LLC
Electronic design, from concept to prototype.
Bringing a project to life?  Send me a message!
 

Offline amyk

  • Super Contributor
  • ***
  • Posts: 8232
Re: Make use of an old CGA monitor
« Reply #35 on: May 25, 2015, 01:52:25 pm »
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.
 

Offline npelovTopic starter

  • Frequent Contributor
  • **
  • Posts: 330
  • Country: bg
    • Microlab.info
Re: Make use of an old CGA monitor
« Reply #36 on: June 18, 2015, 01:28:34 pm »
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.
 

Offline McBryce

  • Super Contributor
  • ***
  • Posts: 2678
  • Country: de
Re: Make use of an old CGA monitor
« Reply #37 on: June 18, 2015, 01:54:14 pm »
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.
30 Years making cars more difficult to repair.
 

Offline rr100

  • Frequent Contributor
  • **
  • Posts: 339
Re: Make use of an old CGA monitor
« Reply #38 on: June 18, 2015, 02:29:59 pm »
I remember the times when I couldn'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...
 

Offline P K

  • Newbie
  • Posts: 8
  • Country: us
  • "Close enough."
    • Don't Quit Your Day Job...
Re: Make use of an old CGA monitor
« Reply #39 on: June 19, 2015, 04:51:53 am »
Quote
I 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.

How 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.

 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: Make use of an old CGA monitor
« Reply #40 on: June 19, 2015, 08:59:49 am »
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=108038

Combined with this $5 3 bit per color R2R DAC module:

http://www.wvshare.com/product/VGA-PS2-Board.htm

The 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.
 
« Last Edit: June 19, 2015, 09:06:51 am by miguelvp »
 

Offline npelovTopic starter

  • Frequent Contributor
  • **
  • Posts: 330
  • Country: bg
    • Microlab.info
Re: Make use of an old CGA monitor
« Reply #41 on: June 19, 2015, 04:53:45 pm »
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.

Because 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 peanuts IBM PC/AT x286 Computer. I tried local search - no one is giving these cheaply.

I remember the times when I couldn'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...

I 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.

How 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/

I 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.

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

I 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".
« Last Edit: June 19, 2015, 04:59:48 pm by npelov »
 

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 3231
  • Country: gb
Re: Make use of an old CGA monitor
« Reply #42 on: June 19, 2015, 05:07:58 pm »
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.0V

This 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
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: Make use of an old CGA monitor
« Reply #43 on: June 19, 2015, 05:57:25 pm »
I 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".

The 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.
« Last Edit: June 19, 2015, 06:22:48 pm by miguelvp »
 

Offline P K

  • Newbie
  • Posts: 8
  • Country: us
  • "Close enough."
    • Don't Quit Your Day Job...
Re: Make use of an old CGA monitor
« Reply #44 on: June 20, 2015, 06:07:43 pm »

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.


Pretty 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.
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: Make use of an old CGA monitor
« Reply #45 on: June 20, 2015, 08:16:06 pm »
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@60Hz

It 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/#msg606242

The 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

« Last Edit: June 20, 2015, 08:23:07 pm by miguelvp »
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: Make use of an old CGA monitor
« Reply #46 on: June 20, 2015, 09:24:39 pm »
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.
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: Make use of an old CGA monitor
« Reply #47 on: June 21, 2015, 03:00:12 am »
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: [Select]
            switch (y%3)
            {
                case 0:
                    switch (x%3)
                    {
                        case 0:
                            frame[y][x] = RED;
                            break;
                        case 1:
                            frame[y][x] = GREEN;
                            break;
                        default:
                            frame[y][x] = BLUE;
                            break;
                    }
                    break;
                case 1:
                    switch (x%3)
                    {
                        case 0:
                            frame[y][x] = GREEN;
                            break;
                        case 1:
                            frame[y][x] = BLUE;
                            break;
                        default:
                            frame[y][x] = RED;
                            break;
                    }
                    break;
                default:
                    switch (x%3)
                    {
                        case 0:
                            frame[y][x] = BLUE;
                            break;
                        case 1:
                            frame[y][x] = RED;
                            break;
                        default:
                            frame[y][x] = 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:

« Last Edit: June 21, 2015, 03:23:25 am by miguelvp »
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: Make use of an old CGA monitor
« Reply #48 on: June 21, 2015, 10:56:52 am »
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 Hz
vertical refresh  15.980 kHz
Pixel freq           7.1590909090909090909090909090909 MHz

Visible area     320
Front porch    8
Sync pulse     80
Back porch     40
Whole line      448

Visible area     200
Front porch    6
Sync pulse     18
Back porch     24
Whole frame   248

But I was able to make it lock at 640x400@70Hz using the timings here:
http://tinyvga.com/vga-timing/640x400@70Hz

Because 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 M3

Here 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: [Select]
            index = (x*2+y)%16;
            frame[y][x] = index|(index+1)<<4;

The hardware blocks take care of the rest :)

Edit2:
Here are the resources used/free
Code: [Select]
------------------------------------------------------------
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 :    5
DMA 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.
« Last Edit: June 21, 2015, 11:58:43 am by miguelvp »
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: Make use of an old CGA monitor
« Reply #49 on: June 21, 2015, 10:31:53 pm »
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.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf