$1 entry to 1kB challenge

Let's use 1-dollar 8-pin PIC12C508A that has 512 words of program ROM (that is 768 bytes) and 25 bytes of data RAM...

Similar projects worth following
... and connect it to NTSC TV ;)

As I said above PIC12C508A has 512 words of 12-bit program ROM so it equals 768 bytes and data RAM 25 bytes don't count (if I correctly understood 1kB Challenge rules) so technically speaking I have spare 256 bytes to fill by (for example) external character ROM! Also it is possible to use more than 1 chip (as soon as all of them are having the same code)...

Note: 1-dollar version is one-time programmable, but I have ultraviolently-erasable one (see picture) for development and final version will be burned into OTP ones forever. Actually, there is a flash version of this PIC (called PIC12F... and it's even cheaper), but because I use old tools I can not program flash version that is relatively new - may be somebody later will test final code on the flash device, but I don't have them and don't want to waste my time by investigating how it could be burned.

P.S. It's interesting to find out how much I can put there :)

PIC12C508A is 8-pin microcontroller with 12-bit program ROM (512 words) and 25 bytes of data RAM. See pinout below that was taken from PIC12C508A datasheet:

It has 4 MHz internal oscillator, but external crystal or clock is also possible (chip will have less GPIO then). One button could be connected to GP3 (because it's input only). GP0,GP1,GP2 may encode 1 color out of 8 (or 8 shades of gray). GP4 may be SYNC. GP5 may be used for something else (most likely for external RC if internal RC oscillator will not be good enough).

4 MHz clock will give us 1 million instructions per second (only a few instructions twice as longer - for example CALL, GOTO etc) or 1 uS. In case of NTSC (see we need to produce something like this:

It means 63.5 instructions per line - it is not possible, so we need to produce not exactly standard NTSC signal to keep integer number of instructions per line - for example with 64 uS per line and 262 lines it will be 59.64 FPS instead of standard 59.94 - it might be acceptable. Also in visible part of the line we may have 52 distinguishable visual elements - probably because of safe area of most of TVs actual working range will be about 48. In case of 4:3 then we may have 36 vertical elements to make them squares (or 27 in case of wide screen 16:9).

It looks like internal RC is good enough for generating stable grayscale NTSC video, but PIC12C508 is too small to put some logic along with NTSC static frame generation. I'll try PIC12C509 to make something useful...

hex - 2.40 kB - 01/06/2017 at 04:31


asm - 7.96 kB - 01/06/2017 at 04:31


inc - 3.45 kB - 01/06/2017 at 04:31


  • 1 × PIC12C508A Microcontroller OTP
  • 1 × 330 Ohm Resistor from GP2 to VIDEO
  • 1 × 680 Ohm Resistor from GP1 to VIDEO
  • 1 × 1.5 KOhm Resistor from GP0 to VIDEO
  • 1 × 1 KOhm Resistor from GP4 to VIDEO

View all 7 components

  • Final fix

    SHAOS01/08/2017 at 02:51 0 comments

    I corrected last line to compensate 3-cycle overhead for every frame and also fixed order of patterns at the bottom of the screen - perfect version to burn my 1st OTP MCU :)

    Final version is 445 words long (87% of PIC12C508) and available on GitLab

    Source code also has schematics in it as a comment:

    ;       +5V
    ;      .--*
    ;      #  |  PIC12C508
    ; 470* #  |   ---v---
    ;      #  \--|1     8|- GND
    ;      | NC -|2     7|--###-\  1.5 kOhm
    ; SYNC *-----|3     6|--###--* 680 Ohm
    ;      | IN -|4     5|--###-/| 330 Ohm
    ;      |      -------        |
    ;       ----------------###--*---> VIDEO (8 gray levels)
    ;                     1 kOhm

    UPDATE: Another 2 TVs running by OTP PC12C508A, both SONY - big CRT one (4:3):

    and big LCD one (16:9):

    with video :)

    As you can see last few shades (5,6,7) are too bright and looks all white (may be because of 1.5V max amplitude). Also there is a space for 48th column on the left side - I'll add it in the next version that will be re-written for heavy macros usage to represent repeating code for visibility purposes...

  • Fixed

    SHAOS01/06/2017 at 05:45 7 comments

    It's already a little bit too late, but this is a fix to make frame sync work :)

    --- a/PIC12-T1.ASM
    +++ b/PIC12-T1.ASM
    @@ -23,7 +23,7 @@ Line_:
      movwf TempN ; 1/7
     Line_loop: ; 15*3-1=44/51
      decfsz TempN,f ; (1/1)
    - goto Line0loop ; (2/3)
    + goto Line_loop ; (2/3)
      nop ; 1/52
      clrf GPIO ; 1/53 -> video 48
    Now image is solid:

    Files in the project still have version without frame sync, but GitHub is fixed

    P.S. Top of the image is a little off because of GOTO at the and and CLRF in the beginning of the program - 3 extra cycles per frame that should be eliminated in future version...

    ANALYSIS: As you can see it's only 4 different brightness levels, not 8 - In this version of the program GP2 is not set as output because T0CS in OPTION register has to be cleared (it's 1 by default) if we need to use GP2 as output. Also you can see 47 columns, not 48 - I'll fix it in the next version...

    FIX for OPTION:

    --- a/PIC12-T1.ASM
    +++ b/PIC12-T1.ASM
    @@ -8,8 +8,8 @@ LineN EQU 0x08 ; line counter
     TempN EQU 0x09 ; temporary counter
      movwf OSCCAL ; store factory calibration value
    - movlw 7
    - movwf Seven
    + movlw 0xC0
    + option
      goto loop
    New screenshot with 8 shades of gray:

    It's patterns 1,2,3,4,5,6,7,0 (incf) and 1,6,1,6,1,6,1,6 (comf)

    Also I reduced pull-up resistor (from GP4 to +5V) - now it's 480 Ohm (too small?):

  • 1st run

    SHAOS01/06/2017 at 04:36 0 comments

    I connected 1.5 kOhm resistor to GP0, 680 Ohm to GP1, 330 Ohm to GP2 and 1K to GP4 (sync) - all of them connected together create analog VIDEO. Program for PIC12C508A is PIC12-T1.ASM (429 words or 643.5 bytes). Result:

    Trying to see what is going on - probably just resistor values have to be corrected...

    UPDATE: After pulling-up GP4 with 2K resistor it's a little bit more stable:

    Test setup:

  • Line of the Raster

    SHAOS01/05/2017 at 06:05 0 comments

    So we will have 64 uS line where:

    - 4 is blank before sync
    - 5 is a sync
    - 7 is blank after sync
    - 48 is visible screen

    PIC12C508/509 don't have interrupts, so we will simply call Line(s) subprogram(s) multiple times to generate proper raster:

    ; call ; 2/2
     nop ; 1/3
     nop ; 1/4
     ; video 48 instructions /52
     clrf GPIO ; 1/53 -> video 48
     nop ; 1/54
     nop ; 1/55
     movlw 0x08 ; 1/56
     tris GPIO ; 1/57
     incf LineN,f ; 1/58 -> sync
     nop ; 1/59 -> sync
     nop ; 1/60 -> sync
     movlw 0x18 ; 1/61 -> sync
     tris GPIO ; 1/62 -> sync
     retlw 1 ; 2/64
    For frame sync it will be special Line subprogram...

View all 4 project logs

Enjoy this project?



Alexander wrote 03/27/2019 at 06:33 point

This is... incredible! Generating video is something I've been meaning to tackle. It's good to see that it can be done so simply -- most writeups I've seen make it look stupidly hard. I went through your .asm and .lst files to look at the generated code, and it's incredible that it can fit in so little program space!

Bravo, awesome work! I love working with tiny microcontrollers like this, but lately I've been spoiled -- working with PIC32MX270F256D with 256k of flash and 64k of RAM!!! Pretty huge difference compared to 25 words of RAM... wow! Also worked with the TM4C129XNCZAD ... 1024k of flash, 256k of SRAM, 6k of EEPROM and the best part -- the microcontroller's libraries are built in to an on-board ROM chip! So the library routines take up no room in your code, if you build it right. Talk about spoiled rotten! The datasheet is almost 2200 pages long: It's probably my favourite microcontroller of all time. It's about $30, hahaha. Very different from the PIC12!!!

Anyway, I really enjoyed looking at this project. Keep up the great work!

  Are you sure? yes | no

greenaum wrote 01/08/2017 at 22:07 point

Regarding your inability to program the flash PIC parts, there's plans online (more than a few) to program PICs using an Arduino. Arduinos are dirt cheap, $3 or so for a nice cheap one. It would save you time waiting for the ultraviolent light to clear EPROM bits. Of course you'd need to get a few of the flash PICs too, but they're cheap too.  

Apart from that, this is a nice project! I'm thinking up stuff you could use this for, is there enough RAM to store a bitmap of the screen, or does it have to be coded?

The Atari 2600 had 128 colours, and no video RAM, the screen was generated line-by-line in software running from the ROM cartridge. It had registers that affected fairly low-level simple video stuff, Hsync and Vsync timing both relied on software. And it had hundreds of games! Each one with a little display kernel drawing the screen, then a little bit of game logic often done during the Vblank period.

As far as a hypothetical game kernel goes, you'd design the code around how you want the screen to look. So issues with how to write to individual pixels, you could work out beforehand, and do the odd individual calculation of, say, changing 1 or 2 pixels at a time, during Vblank.

So with a bit of thought about how to draw each part of the screen, from a vertical point of view, going downward each line (but you're already doing that!) you could write Breakout or something simple. Tetris might need more than 1K!

  Are you sure? yes | no

SHAOS wrote 01/08/2017 at 22:23 point

RAM is only 25 bytes (41 for PIC12C509), so image has to be coded :)

But to code something dynamic I need bigger device like PIC12C509 at least (with 1Kword of program)

and I already got cheap Chinese USB-programmer to program everything ;)

  Are you sure? yes | no

Ted Yapo wrote 01/09/2017 at 00:53 point

LOL, I just bought one of these myself a few weeks ago to program GAL16V8's.  My older programmer needed to run under Windows, which I no longer have...

  Are you sure? yes | no

SHAOS wrote 01/09/2017 at 04:26 point

Hm, which OS you use with this one? I thought it requires Windows, so I run it on the only WinXP machine that I have in my house (all others work under Linux, MacOS or DOS)

  Are you sure? yes | no

Ted Yapo wrote 01/08/2017 at 21:10 point

I wonder what you could put in one NTSC image?  Maybe make a version that displays a single fixed QR code on the screen.  The QR code is a link to a web site. You could make cheap little modules to plug into unused composite inputs for some kind of guerrilla marketing campaign.

  Are you sure? yes | no

SHAOS wrote 01/08/2017 at 21:14 point

I'm trying to come up with an algorithm that will convert any image 48x27 into program for PIC12C50X. Problem is it can't be arbitrary value in every single cell, because arbitrary value will require additional MOVLW command so previous "color" will occupy 2 cells. So it has to be some tricks like rotations, swaps, inc/dec etc. Also it's interesting to analyze 4 colors (2 bits per cell) vs 8 colors (3 bits per cell) in terms of possibility to represent ANY image 48x27 (display any possible patterns in the row).

  Are you sure? yes | no

SHAOS wrote 01/08/2017 at 22:08 point

Another possibility is to switch to black and white with shifting 4 bits with external shift register - in this case it will be up to 192x216 visible resolution (but black and white)...

P.S. From other hand it's easier to switch to 20MHz PIC16F505 (84 cents on digikey) and have shift register inside of the chip (like RRF PORTB,f multiple times)

  Are you sure? yes | no

Ted Yapo wrote 01/09/2017 at 00:52 point

The 16F505 is a nice part, too.  I used one in a stepper controller board at one point; again very simple and no complex peripherals to initialize.

  Are you sure? yes | no

Ted Yapo wrote 12/09/2016 at 20:47 point

I really like the '508s (and '509s).  They're so simple - without all the overwhelmingly complex peripherals. Just write code and it runs. I have a partial tube of each left from previous projects - and some of the flash ones.  If anything I did ever felt "finished," I'd burn more of the OTP ones :-)

I also like the thought of ultraviolently erasing the windowed parts.

When you have some code to test, I can give it a try on the flash version.

  Are you sure? yes | no

SHAOS wrote 12/10/2016 at 02:09 point

Great, thanks :)
I have both PIC12C508A and PIC12C509A (OTP and UV), but 509 is not qualified for "The 1kB Challenge" because of 1024-word ROM :(

Also I never actually used PIC12 yet, even though I own the chips since 2004, but I played a lot with SX28 that was PIC16C57 "on steroids" (with one instruction per clock with 75 MHz clock) and they have the same instruction set as PIC12...

BTW I have a bunch of PIC16C54 as well (both OTP and UV)

  Are you sure? yes | no

K.C. Lee wrote 12/10/2016 at 02:56 point

As long as you don't use more than 1kB, then it is still okay.

  Are you sure? yes | no

SHAOS wrote 12/10/2016 at 12:05 point

1kB is 682 12-bit words or 66.6% of the 509's ROM - I'll think about it, but it will not be $1 entry anymore, because price of that chip is about $1.5 :)

  Are you sure? yes | no

K.C. Lee wrote 12/10/2016 at 15:14 point

If you want cheap, there are $0.22 STM8S003 and $0.44 STM32F030.  :P  I used the latter for VGA and NTSC.

  Are you sure? yes | no

SHAOS wrote 12/10/2016 at 16:06 point

I like predictability and reliability of PICs :)

  Are you sure? yes | no

Ted Yapo wrote 12/10/2016 at 20:00 point

12C509A is $0.99 in 100 quantity

I think that counts - just make your project so good/useful that at least 100 will get made :-)

  Are you sure? yes | no

SHAOS wrote 12/10/2016 at 21:36 point
ok, I'll keep this in mind

  Are you sure? yes | no

SHAOS wrote 12/11/2016 at 00:27 point

something funny happened with my last reply - it's multiplied...

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates