XORYA - extremely low cost game console on PIC32

XORYA game console is just one chip PIC32MX170F256B (32-bit MIPS core, 256K flash, 64K data mem) in DIP28 package and a few other components

Public Chat
Similar projects worth following
XORYA is extremely low cost game console that consists of just 1 chip (in its base configuration) - DIP28 integrated circuit PIC32MX170F256B (32-bit MIPS core, 256K flash, 64K data memory) and a few capacitors and resistors with total cost below $5. XORYA is connected to NTSC TV through composite video input and it's running applications created with help of open source game library XORLib ( ) specifically developed for this platform. XORYA may produce a number of black and white video modes (with 640x200 maximum resolution) and (potentially) stereo audio with 15734 Hz sample rate (through PWM). Also with external crystal 14.31818 MHz and 2 more capacitors it may produce color NTSC signal similar to "composite" mode CGA with 16 colors (actually 15, because 2 gray colors look the same) and resolution 160x200.

Project is based on "NTSC TV interface" examples from by @Bruce Land (Cornell University), which are based on examples from "Programming 32-bit Microcontrollers in C: Exploring the PIC32" by Lucio Di Jasio. I switched text mode to my own 8x8 font and eventually dropped support for original 256x200 resolution and focused on newly introduced 320x200 and 640x200 video modes. Adding color to generated NTSC signal was inspired by KenKen's work, but nothing from that software/hardware was used here because goal of my project was not about getting perfect colors, but to get simplest (and cheapest) circuit that generates a number of distinguishable colors on NTSC TV. Accidentally I reinvented "composite mode" used in earlier CGA (when every 4 black and white pixels in the row confused NTSC TV to detect different colors depending on pixels pattern) with the same resolution 160x200 and very similar palette (actually 4 palettes of the same 16 colors are supported: 0 - original XORYA palette, 1 - palette similar to CGA composite mode, 2 - palette similar to Tandy composite mode, 3 - palette similar to PCjr composite mode, where "similar" means color phase is shifted back about 30 degrees versus original):

To make video memory compatible with CGA I also changed 32-bit DMA-to-SPI to 8-bit (because SPI sends higher bit first and in case of 32-bit it works as big-endian, but it has to be a little one) and surprisingly it did not negatively affect performance (text mode even became 43% faster because now it is not required to mask single byte in the word to write a character). And before adding project here the progress was reported on DangerousPrototypes forum.

Current schematics (for generating color NTSC signal, no audio or inputs yet) with external crystal 14.31818 MHz (it must be precise):

It generates this waveform with "color burst" in the beginning of every line:

Simplest Black-and-White NTSC version (no color) with internal oscillator:

This version is a little bit faster because it's running on 60 MHz core frequency instead of 57.27272 MHz as previous one.

Also note that 6-pin header is required if you need to reprogram the chip by PICKit3:

  1. MCLR (pin 1)
  2. 3.3V (pin 13)
  3. GND (pin 8)
  4. PGED1 (pin 4)
  5. PGEC1 (pin 5)
  6. Not connected

To build something with XORLib you need MPLAB.X IDE and XC32 compiler (but NOT new one, it has to be v1.34 or older because of plib.h - old versions could be found here ).

Cheapest possible implementation of Xorya is Xorya Touch where controls (both gamepad and buttons) are drawn by copper on PCB itself...

  • 1 × PIC32MX170F256B PIC32 microcontroller with 256K flash and 64K data memory
  • 1 × 0.1 uF Ceramic capacitor
  • 1 × 10 uF Ceramic capacitor
  • 1 × 10 kOhm Resistor
  • 1 × 330 Ohm Resistor

View all 8 components

  • Xorya on RISC-V?

    SHAOS01/20/2019 at 16:54 1 comment

    Recently I made a lot of activities around RISC-V open architecture and even created my own RV32I implementation that passed majority of compliance tests (except 1 about unaligned jumps) - see nedoPC-5 project . So then I've got an idea - what if I put Xorya framebuffer (with control logic) to the same FPGA with RISC-V core? Then I'll be able to load Xorya programs from external storage (as SD-card for example), add serial, ethernet etc.  Porting XORLib to this new system should be relatively easy task because it's written in C (only some Microchip specific things as SPI+DMA handling should be re-written). What do you think? Please leave a comment below...

  • Possible extension of Xorya to true CGA

    SHAOS11/09/2018 at 06:10 0 comments

    In October 2016 I tested (but didn't share here) a simple circuit that used not only SPI data output as orignial Xorya, but also SPI sync, and consisted of one 74F00 and two 74F74s that (with help of NTSC color generator chip AD725) may allow us to get "true" CGA 4-color 320x200 mode with the same PIC32 and slightly extended XORLib (so it might be the next generation PIC32 video console Xorya-II capable of running some classic CGA games from PC):

    Problem is I didn't capture actual schematics at that time and now I don't remember how exactly it worked...

  • Screenshots

    SHAOS01/25/2017 at 05:49 0 comments

    Just a few screenshots as an example of what Xorya can do on NTSC TV with 15 colors (original images were taken from Internet under "fair use"):

    ( source of the city image is )

    and some images taken from old PC games:

  • Prototype Xorya-I

    SHAOS11/12/2016 at 01:35 1 comment

    This is a prototype of the actual Xorya game console as it will look (codenamed "Xorya-I"):

    As you can see it is "Direct-to-TV" kind of gamepad with 2 buttons on the right (green and red) and analog joystick on the left (currently it's 2-axis joystick from Parallax that costs more than $5). With composite video cable you can see cables for stereo sound (generated by 2 PWM). Later I'll add 2xAAA case on the back and power switch (it's not needed yet while I use PICKit3 to play with it).

    Interesting thing is the fact that PIC32 chip is actually a cartridge with the game ;) In order to simplify process of inserting and removing of such game I put there a ZIF-socket (cost about $10). So the big idea is to present Xorya as an open source indie game platform with dedicated online store that will sell actual physical retro looking games for it (in form of preprogrammed PIC32 chips) both open source and proprietary with prices $5 and up.

    Calculating everything (including future PCB of that size) I got possible retail price for the product (if I finally make it) - $29.95 (1 console plus 1 chip with "free" game). Thoughts?...

  • Xorya Superdemo

    SHAOS11/08/2016 at 17:00 9 comments

    For people who didn't notice my little demo on Hackaday Superconference during last weekend - this is 5-minute video:

    Source code of the demo:

    This is a collection of some XORLib examples that I created since April 2015 plus couple new pieces of code combined into a single C-file (also 2 additional data files are required and of course XORLib - everything is there on GitLab). Enjoy ;)

    UPDATE: Prebuilt binary in HEX form is available on GitLab:

  • PCB as a gift

    SHAOS10/13/2016 at 02:42 7 comments

    I forgot to mention that some time ago I received a few PCBs of Xorya prototype with composite connectors as a gift from @arnaud.durand

    Thank you, Arnaud! :)

    P.S. I can give away few pre-built Xoryas with hotglued batteries and pre-installed "fast" Mandelbrot Set demo on Superconference in Pasadena, if anybody is interested :)

  • Latest update

    SHAOS03/08/2016 at 23:15 0 comments

    Hi All, I'm still here :)

    Recently I'm successfully tried to connect Xorya prototype to cheapest available color NTSC TV (from ebay) and it was working pretty well:

    Last year I put this project into pause mode mostly because I stuck a little because I was not able to decide where to develop this project further - I have 3 choices:

    - put it into NES gamepad and program support for NES and SNES serial gamepad protocols;

    - design board around DIP version of PIC32 in form of gamepad with buttons - 4 buttons on the left for direction moves and 4 buttons on the right for actions;

    - design board around DIP version of PIC32 in form of gamepad with analog joystick on the left and action buttons on the right...

  • Color Combinations

    SHAOS05/15/2015 at 23:36 2 comments

    Experiment with color combination with chess board mixing:

    This is simulation in DOSBox on PC:

    PIC32 on NTSC TV - palette 0:

    PIC32 on NTSC TV - palette 1:

    PIC32 on NTSC TV - palette 2:

    PIC32 on NTSC TV - palette 3:

    Source code:

  • Problems

    SHAOS05/15/2015 at 03:18 1 comment

    For now I have 3 problems:

    1) When I switched from 32-bit DMA-to-SPI to 8-bit (to have video memory ordered similar to CGA) I got gap after 1st byte if transfer is happened on every 2nd peripheral clock (or 14 MHz), so before (with 32-bit transfers) I had bytes displayed in this order:

    After switch to 8-bit DMA-to-SPI I expected to get this:
    But instead I got this (with a gap between byte 0 and byte 1):
    0 123456789ABCDEF...
    I fixed this by shifting visible part 1-byte to the right (anyway I already had this invisible left part of the screen for "color burst" and rest of the "back porch") - any ideas how to setup DMA and SPI on PIC32 chip to eliminate this gap?...

    2) Colors are stable on LCD and LED TVs (I tested it on SONY, LG and Sumsung), but it doesn't work properly on CRT TV (I tested "Last CRT TV" SONY produced in 2005) - instead of solid colors I got red and green spots over black and white pixels - may be crystal is not precise enough to work with CRT and I need to put adjustable capacitor somewhere sequentially?...

    UPDATE: After switching to more precise crystal (14.31818 MHz) I got color on SONY TV as well...

    3) Single color pixel (pattern that consists of 4 black-and-white pixels) not always may produce color (or at least expected color) and 2 different color pixels sitting together may eliminate each other completely, so it is a little tricky to convert arbitrary RGB image to these 15 colors with dithering, so may be I need to write a special software that can do such conversion considering a number of rules of composite colors combinations or may be somebody may advice me to get some existing one?...

  • Fast into Mandelbrot Set in Real-Time

    SHAOS05/13/2015 at 06:02 0 comments

    Faster version with 32-bit fixed point math (at some point it's INCREDIBLY fast) on the same PIC32 running on 57 MHz CPU freq, but obviously less precise - error level doesn't allow to travel deep into the Set and it goes off the track too soon:

    The same source code:

    But with FIXED32 macro instead of FIXED64 and "fake wide-screen" ratio 16:9 (with the same resolution 160x200)...

View all 18 project logs

Enjoy this project?



magnustron wrote 11/09/2018 at 13:56 point

Hi! I really like your schematic diagrams! How did you generate them? Is this circuit outputting its own schematics on a TV screen?

  Are you sure? yes | no

SHAOS wrote 11/09/2018 at 19:55 point

I used my Circuit.CC ASCII schematics editor :)

It used nedofont that is also used in Xorya, so technically yes - Xorya may output its own schematics on TV screen in 640x200 black-and-white mode ;)

  Are you sure? yes | no

SHAOS wrote 10/22/2018 at 03:36 point

I can try to port XORLib to #2018 Hackaday Superconference Badge 

  Are you sure? yes | no

Mike Szczys wrote 10/22/2018 at 21:46 point

Wow, that would be epic! I'd love to see the badge doing some handheld gaming like this!

  Are you sure? yes | no

SHAOS wrote 10/27/2018 at 01:54 point

Problem is that TFT controller on the badge should receive sequence of at least RGB565 values, but XORLib must have videomemory inside of PIC32 and it can not be RGB565 because it has only 128KB of RAM onboard (320x200 with byte per pixel is 64000 bytes already), so videomemory will be still low number of colors like 2 bits per pixel or 4 bits per pixel as in original Xorya and then I should convert sequence of low-color pixels to RGB565 (in software!!!) after every change to feed TFT controller through DMA...

  Are you sure? yes | no

SHAOS wrote 06/07/2018 at 03:01 point

Moved source code of XORLib to GitLab:

  Are you sure? yes | no

arnaud.durand wrote 07/16/2015 at 11:46 point

Is the 10k resistor required if we connect MCLR directly to the PICkit3? Can't wait to try Mandelbrot.

  Are you sure? yes | no

SHAOS wrote 09/10/2015 at 21:49 point

I'm not sure - I always have it

  Are you sure? yes | no

dave wrote 06/27/2015 at 20:02 point

Wow, that's so amazing, congratulations!

  Are you sure? yes | no

arnaud.durand wrote 06/15/2015 at 16:17 point

This project is awesome and I want to build mine. Do you know what is the difference between PIC32MX170F256B-50I/SP and PIC32MX170F256B-I/SP? Which one do you use?

  Are you sure? yes | no

SHAOS wrote 06/17/2015 at 02:36 point

PIC32MX170F256B-50 is for 50MHz and I suspect it could work on 100MHz core freq (because regular one PIC32MX170F256B that I use is 40MHz and it can work on 80)

  Are you sure? yes | no

Hacker404 wrote 05/16/2015 at 03:26 point

How are you getting 16 colors from one GPIO?  Are you using CTC's to phase split the color burst freq into exact 22.5 degree sectors or perhaps just roughly timing with CTC/INT and relying on the CPU clock to maintain sync to color burst (sub-carrier) freq?

  Are you sure? yes | no

SHAOS wrote 05/16/2015 at 09:28 point

No, I simply send bits out through DMA and SPI (so CPU is involved only in setting this up in the beginning of every scanline by interrupt) with precise frequency 14.31818 MHz and color burst zone is also part of videomemory - it's like


then NTSC TV caught different colors from patterns 0010 0011 0111 etc.

P.S. It's identical to "Composite CGA" technique - see 


  Are you sure? yes | no

Hacker404 wrote 05/16/2015 at 14:18 point

Ah, so splitting into 90 degree sectors. Sending 4 bits per color sub cycle and hence the res of 160px width => (Scanline / color sub) * 4. So chroma is 0 to 4. 0 for black, 4 for white and 1, 2 or 3 for everything else. 

One (4 bit) cycle per pix and hence the boundary bars between colors. This could work much better at 2 or four times the clock freq and repeating the bit pattern 2 or 4 times but short of PLL it would be hard to generate these frequencies.

  Are you sure? yes | no

Hacker404 wrote 05/16/2015 at 14:33 point

PS: The color boundary bars are predictable and you could code to prevent them by adding / removing bits that keep the chroma in an even transition rate and at the same time balancing the phase (as best can be done with 4 bits). 

ie going from color 1000 to color 0001 does not need chroma correction as both are 1 but sending 0100 0010 for adjacent pixels may correct the phase for the boundary bars.

  Are you sure? yes | no

SHAOS wrote 05/16/2015 at 21:04 point

If I'll manage to have 1280 pixels per scanline instead of 640 then I most likely support more PC modes as 320x200/16 colors and 640x200/4 colors with a little help of external hardware in form of a PAL/GAL, because 160x200 is not good even with perfect colors...

  Are you sure? yes | no

Hacker404 wrote 05/16/2015 at 22:14 point

There is a limit with composite TV signals because they were bandwidth limited to get many channels over air. Both NTSC and PAL have a sound sub-carrier that is not much higher than the chroma/luma so the input circuitry in the TV has cut-off filtering. 

The old retro computers squeezed as much as possible out of TV's before abandoning them and going to monitors. The last standard that TV like or compatible was CGA.

Compounding these limits, is the fact that you are using a square wave. It is in fact the attenuating effect of the boundaries of the TV's input filtering that are somewhat 'correcting' this generated signal so that the following chroma/luma circuitry can decode it. 

The base frequency of a square wave is the reciprocal of it's period. A rectangular wave has two base frequencies. One each that are the reciprocal of twice that active '1' period and also the reciprocal of twice the in-active '0' period. 

By changing the duty cycle so that you have a very low or very high duty cycle you are relying on a much higher frequency component that may well me lost in the TV's input filtering. This is the limit.

The advantages of the the circuit here are that by having a simple DAC the output is less square like and more sine like. The second advantage is that chroma and luma can be generated separately. 

Your circuit has no chroma control. The resulting chroma from your circuit is simply the number of '1's in each group of four and that is why you have bands between colours. 

So 0011 has chroma of 2 and 1100 has chroma of 2 but the four middle bits between the two nibbles  (11 11) have the chroma of 4 and hence the bands. At the same time the phase transition is averaged giving a different color.

It would very interesting to test this with PLL and CPLD/FPGA but for me I am going with VESA standards for (x)VGA. 

It will very interesting to see how far you can go with horizontal pixel resolution. PAL ('I' and 'BG') has 625 lines interlaced 2:1 ie 312.5 lines per frame offset by one line so it may give reasonable results. Not all of these are visible. 

Good luck, I will be watching keenly to see how you go.

  Are you sure? yes | no

SHAOS wrote 05/16/2015 at 23:27 point

In the last 12 years I'm writing software for TV cable boxes connected to NTSC TV through composite video input (as one of the possible ways) and those boxes have max resolution 640x480 with 16-bit color pixels and I see this as a true limit of NTSC (480 interlaced of course). Also I came from SECAM world and I still remember as 625 interlaced lines look like with their 50 FPS (25 full frames per second) - anyway I like American 60 FPS better with slightly lower resolution (60 half-frames of course ; )

  Are you sure? yes | no

Andrew Pullin wrote 05/14/2015 at 01:56 point

How about dsPIC? They can be clocked up to 80mhz, have a bunch of DSP accelerated functions already provided by Microchip.

  Are you sure? yes | no

SHAOS wrote 05/14/2015 at 02:26 point

PIC32 could be clocked up to 100 MHz - I simply didn't find proper multipliers yet to have NTSC color burst frequency and max possible CPU frequency...

P.S. dsPIC has only 16 bit datapath if I not mistaken

  Are you sure? yes | no

Rollyn01 wrote 05/13/2015 at 08:11 point

Wow, that Mandelbrot Set rendering is amazing. Even more so from a microcontroller. Excellent job.

  Are you sure? yes | no

SHAOS wrote 05/13/2015 at 13:41 point


  Are you sure? yes | no

AVR wrote 05/13/2015 at 06:07 point

this is really neat and quite impressive.

  Are you sure? yes | no

SHAOS wrote 05/13/2015 at 06:11 point


  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