TVout using SPI

Here is a project to output a 80x25 character buffer, similar to TVout, but at higher a higher resolution. In order to scan 8X8 characters, I wanted to co-opt the UART in SPI mode for use as a video shift register. Overlapping the video shift out with character ROM lookup would allow on-the-fly character generation at 320X200 screen resolution from a 1000 byte character buffer.

Jan Ostman apparently got something similar working on using a 1284 with 16K of RAM, but I wanted to use a Uno with just 2K of RAM. I couldn’t get anything stable using Jan’s code on my Uno, so I distilled down the code of three separate projects in order to investigate the feasibility of getting this working.

And it does. With the caveat that the SPI seems to glitch quite often and introduces shifted scanlines. I used the TVout video timing values and code because that produces a very stable display. I’m pretty new to the Atmel scene, so maybe I’m missing something with the SPI interaction. I thought others could look it over and point out my obvious mistake :wink:

This is hard-coded for NTSC on an Uno. Use Pin 1 (TX) for VIDEO, pin 9 for SYNC.

Find updates on github Arduino/VideoSPI at master · dschmenk/Arduino · GitHub

Gratuitous screenshot. Notice the shifted scanline going through the words “SPI Demo”:


Replying to myself here: after carefully reviewing Nick Gammon's nice VGA code, I realized I didn't turn off timer 0 interrupts. All cleaned up, now.

Now that I worked out the issues with the SPI and timer0 interrupts, I put together a quick demo video. I edited the font to use box drawing characters and lo-res 2x2 pixel block characters for some kind of graphics functionality (just 80X50 pixels). By using boring old composite video, it leaves a significant amount of processing left over for the 328. And by using the SPI hardware it gives a nice, high resolution image but needs just 1000 bytes of memory for the character buffer. I had to slow down the demo to only update once per frame or otherwise it was just a blur.


Great project. Theres a Zork emulator for the arduino that uses a similar technique. I wonder if you could turn this into a VT100 terminal?

Thanks for the heads-up on Zorkduino - a great project incorporating keyboard and SPI communication with video. That was a lot of work just to play Zork from the couch, but very cool. I'm not sure where I'll take this project, but I do have an ethernet shield lying around...

Excellent application is displayed perfect :slight_smile: , I’m just an enthusiast and very inexperienced, how is it possible to add more ASCII characters? since in the Extended ASCII characters for example from 176 to 224 can be very useful to generate interfaces (windows, buttons, …)

(16 ►, 17 ◄, 30 ▲, 31 ▼ ,174 « ,175 » ,176 ░ ,177 ▒ ,178 ▓ ,179 │ ,180 ┤ ,181 ╡ ,182 ╢ ,183 ╖ ,184 ╕ ,185 ╣ ,186 ║,187 ╗ ,188 ╝ ,189 ╜ ,190 ╛ ,191 ┐ ,192 └ ,193 ┴,194 ┬ ,195 ├ ,196 ─ ,197 ┼ ,198 ╞ ,199 ╟ ,200 ╚ ,201 ╔ ,202 ╩ ,203 ╦ ,204 ╠ ,205 ═ ,206 ╬ ,207 ╧ ,208 ╨ ,209 ╤ ,210 ╥ ,211 ╙ ,212 ╘ ,213 ╒ ,214 ╓ ,215 ╫ ,216 ╪ ,217 ┘ ,218 ┌ ,219 █ ,220 ▄ ,221 ▌ ,222 ▐ ,223 ▀)

I suppose that the characters are defined as a block of 8 by 8 pixels, and are called to call as a letter and not as an array of pixels.

So you could define tiles of 8 x 8 to one bit, so you could implement large graphics based on blocks of 8 x 8 defined in the program memory.

Maybe my questions are a bit strange, I appreciate your attention, my English is not very good, I’m working with the Google translator.

Looks great!!

sorry if my English is not very good done some simple experiments, and manipulated a bit the information of the tiles of the typography e modified and replaced by graphics orros. I have not basically changed the essence of the project. And I reaffirm that the resolution and the aspect is very good and much more showy than the classic tvout :slight_smile:

How to plot a single pixel? There is a simple way to do it?

Place a single pixel, it does not work that way it prints a block of 8 by 8 pixels and in program memory these blocks of 8 by 8 pixels are saved. that's why the resolution of 320 X 200 is unlike the TV out ( with only 128 x 96 pixels.
For each horizontal scan, draw 40 blocks of 8 pixels.

comrades I need your help and I can not find a way to integrate an NES contros into this project although the routine is correct for some reason it only detects when I press the "B" button.