Dissecting a hand-held NOAC console (Sup 400-in-1)

This is an attempt to understand how these little things work, and what we can do on it.

Public Chat
Similar projects worth following

This is an attempt to dissect and to understand how these little handheld NOAC (Nintendo-on-chip) consoles that are being sold for around $5 in the market.

You can read more about the NOAC on the Wikipedia page:

We know that this thing in the black epoxy has the clone of the Nintendo Entertainment System. Upon further reading, there's more to being the clone too - possibly an enhanced version like the VT-series (

What's inside it? How does it work? Could I load its ROM another new code? That's the question!


TFT lines on the board.

Bitmap Image File - 6.32 MB - 10/11/2020 at 12:53



ST7789 16-bit 8080-II interface datasheet.

Portable Network Graphics (PNG) - 513.85 kB - 10/11/2020 at 12:35



COB Flash and NOAC on board with the TFT removed.

JPEG Image - 1.27 MB - 10/11/2020 at 12:33


  • 1 × Logic analyzer Recommended a Digital Discovery or Analog Discovery 2

  • Opcodes has its bits swapped??

    NYH-workshop04/11/2024 at 03:51 0 comments

    After from the previous log, I took a look in the EmuVT's debugger and noticed that there are many jumps to a nearby locations and "strange" opcodes that don't make any sense:

    Hmm... looks like some of the stores especially at the $412D could make sense, since these stuff often use the registers around that address. And the jumps too. Look at the end with the "F5FE" - looks like a jump to the main startup code?

    Wait... I recalled about chatting about those VT-02 OneBus systems at NesDev Discord, and also these NesDev article:, and another BGC article:

    Something reminded me that there could be swapped bits somewhere in the opcodes. After checking these instructions on a pen and paper, bits 4 and 5 at the opcodes are actually swapped!

    After swapping these bits manually in HxD and pasted this modified code back, it runs on the EmuVT now!

    These newer Sup 400-in-1 handhelds are having these strange bit-swaps at the addresses, and this one having a bit-swap at its opcodes before the startup happens!

  • Another new romdumper - this time it's faster!

    NYH-workshop04/11/2024 at 03:32 0 comments

    When trying to dump a newer Sup 400-in-1 ROM on my Raspberry Pi based dumper, the thing doesn't load well in the emulator. There are many corruptions in the ROM when viewed through the YY-CHR app. The little dots at the empty area are those corruptions:

    Plus, this thing takes a whole day to dump and it's really slow, and I have a better idea to port this whole thing to a Raspberry Pico instead. After figuring out the newer problems such as the MCP23017s couldn't be detected and these corruptions, I had modifications to the circuit:

    This time, it dumps really fast and about 35 mins later I get the 16 megabytes ROM dump. You can check this ROM dumper here too if you want a faster alternative!

    However, when trying to run it in the EmuVT - it just gives me a black screen and it doesn't work! What gives?

  • Dissecting the startup!

    NYH-workshop03/31/2024 at 03:41 0 comments

    As mentioned in the previous logs, if you have used this method, you may able to get the dump and run this binary in the EmuVT emulator.

    So on about last year, I actually dissected the flow of the program and written it into a piece of paper. This analysis does not include how the game menu works and the test screen - only the startup.

    Using the EmuVT emulator and putting breakpoints one by one, I managed to see things like:

    • Getting the starting address at $7FFFC.
    • Initializing registers at $412B and $412C.
    • Dumping about 15 values into the $4200. 
    • It went on jumping back and forth around addresses $60000 and $70000. Most of the TFT startup and the menu, and Aaronix test screen logic are situated at $60000.
    • OneBus switching seems to be performed in RAM. 
    • The TFT initialization seems to follow a pattern. There are multiple loads and stores, and digging the pattern in Google, the model is actually GC9306. Datasheet here.
    • The register $4233 possibly controls the 16-bit parallel LCD outputs to be a GPIO or the parallel LCD. When it is set at $84, this might becomes a GPIO - during the TFT initialization it does this. When done the initialization routines, this is set at $04
    • The functions that write the command and data to the TFT uses $4230 and $4231. At $4233 again if it is a write command, $94 is written. If it is a write data, $D4 is written.
    • Finally, around the starting point of the game menu, $412C is written $0F to enable the backlight.

    These are also verified using the homebrew flash emulator that dumps part of the ROM ($60000-$80000) into the Teensy 4.1. 

    With the flash emulator, using the stripped ROM, I managed to try adding a while loop at certain places in the ROM (usually 4C xx xx) to 'halt' the program. This is useful when I want to see when the backlight gets switched on. Initially, it is thought that the backlight is switched on at the TFT initialization routines. However, putting the command inside does not work (backlight doesn't lit up), and I had to try adding this 'halt' between the function calls when the menu is running. When one of the locations are being known to switch on the backlight, I focused into it and found out that putting the $0F into the $412C actually does this thing.

    I dumped two of these ROMs (one bought in 2020, and another somewhere later) and one of them have swapped bits 1-2 and 9-10 at the data pins! Some of them have very different starting vectors too - one started at $FF00, and one at $FEF5. However, they all use the same mentioned registers and these apps could possibly work on another similar Sup 400-in-1 consoles.

    One more issue - where are the registers that controls the external sound speakers?

  • It is working, but might not be fully functional!

    NYH-workshop03/23/2024 at 16:54 0 comments

    After looking at the code and checking the Teensy 4.1's processor datasheet, it is known that there are edge interrupts on a row of GPIO pins. It means, if any pins at GPIO6-9 are changed, it triggers an interrupt.

     I'm suspecting that the polling of the address lines by Teensy couldn't catch up with the speed of the switching addresses at the NOAC. Having the pin change interrupt makes it easier for the NOAC to catch the instruction that is fed from the Teensy pins.

    And... yes, there's the game menu, and it jumped into the test screen when I hold the A + B before the thing starts:

    Unfortunately, there are limitations - the Teensy needed to be overclocked to 912MHz to do this successfully, and a heatsink is required. I am now figuring a way to have a fan to blow on the heatsink, and also to write up short pieces of 6502 code to make it run on that NOAC. 

    And here's the Github page if you are interested in replicating the project.

  • Partially working, needs more improvements!

    NYH-workshop03/23/2024 at 15:42 0 comments

    From the previous log... what would happen when a short piece of code is being loaded and run after applying the reset?

    And for a short description on how this is done:

    1. Dump the ROM according to this log - make sure it can run in the emulator!
    2. On the ROM, using the hex editor such as HxD, cut out the range of address 0x60000-0x80000.
    3. Still in the hex editor, create an empty new binary file and paste it in. Save it separately!
    4.  In the Teensy's application, the binary file is being received through Ymodem (using this method) from the PC. 
    5. After receiving the file, the app resets the NOAC on the PCB. 
    6. The app rapidly polls for the address changes (A0-A17) and pushes the data (D0-D15) with the responses from the /OE and the /CE pins too. (Or in other words it's called an EEPROM emulator!)

    Well, it kinda works... but it's a whole lot of mess out there:

     The code was running but the screen was garbled with full of noises and artifacts running around. You can see bits of the menu and the Aaronix test screen and that's much about it.

    Was the Teensy not working fast enough? Or there are wiring mistakes? Hmm... Figuring this out....

  • Another strange idea after a long break...

    NYH-workshop03/23/2024 at 15:16 0 comments

    On and off, I had been experimenting on this but with very little success. 

    There are too many unknowns and trying to guess how it works by modifying the code and reprogramming the flash could be too time consuming.

    Later, I came up with the strange idea of connecting the vacant flash pins on the board to another microcontroller and have this microcontroller pretend it is some form of flash.

    How I did that:

    • Soldered the vacant flash pins with 1.27mm pitch ribbon cables (22 pins each),
    • Taped the soldered wires with the Kapton. The lines on the PCB are very, very flimsy and could not tolerate a lot of movement at the solder points
    • and connect two female IDC sockets (more than 22-pins) on the other end of the wire (not shown here):

    Oh, and a lot of jumper wires to connect this back to the Teensy 4.1 from the end of the female IDC connector . Here is the rough schematic (also note the white cable connected on the Reset Pin which is the "RST"):

    It should be something like this in the end (pardon the mess! I will draw another cleaner diagram for this one!):

    Well, all the pins are connected. Looks frustrating, and I got it done after a few weekends on this!

    What would ever happen if I program the Teensy to manually feed the whole game board some instructions?

  • New Git found: "SUP Console Programmator"

    NYH-workshop02/23/2023 at 15:37 0 comments

    When trying to find ways and means to put our custom compilation inside the flash, I bumped into this very recent article (it is in Russian - you need a Google Translate) explaining about the dumping and the flashing process of the chip inside.

    Also, the author documented the rest of the process in the Github (it is in Russian too - Google Translate works on it) - it is an extremely good read.

    The method would help me to dump and flash the ROM faster, and also to help me understand that program inside better.

    From the article, the pictures are the attempts to build a makeshift "cartridge" that holds that flash board and the "slot" connected to the SUP console:

    (Source: Thanks to Aleksandr Serdyukov -

    On that, I will try to build this too and experiment it! :)

  • Dump complete! Disassembling the Menu in progress...

    NYH-workshop02/23/2023 at 15:25 0 comments

    Finally, after the one whole day it dumped the contents, I immediately used the BIN file to test it in the EmuVT 1.36. (The latest version doesn't work properly, the screen blacked out when scrolling the menu)

    It just worked! Some of the games doesn't work - it could be the dumping issue, or the emulator issue. However, most of the game worked flawlessly:

    (What is Utmost Warfare??? And that music... Urgh!)

    Due to many, many reasons, I felt uncomfortable putting this ROM image here - since the method of dumping is possibly correct, you can replicate this process using the Raspberry Pi, a bunch of wires, and 3 MCP23017s. Here's a rough schematic:

    Here is the Python code - I accidentally did a dump from 0x800000 to 0xFFFFFF, but the contents are mirrored from 0x000000 to 0x7FFFFF so the dump still worked as usual! Use a Raspberry Pi according to the schematic too.

    Caution: The Python code is quite messy - it has not been finalized. This dumping process takes almost a whole day!  

    import time
    from datetime import datetime
    import board
    import busio
    import digitalio
    from adafruit_mcp230xx.mcp23017 import MCP23017
    # ROM dump utility
    print("ROM dump utility")
    # Initialize the I2C bus:
    i2c = busio.I2C(board.SCL, board.SDA)
    mcp00 = MCP23017(i2c, address=0x20)
    mcp01 = MCP23017(i2c, address=0x21)
    mcp02 = MCP23017(i2c, address=0x22)
    # mcp00 = addr (A0-A15) [A+B]
    # mcp01 = addr (A16-A23) [A]; /CE, /WE, /OE [B]
    # mcp02 = data (D0-D15) [A+B]
    # setting data pins:
    mcp02.iodira = 0xff
    mcp02.iodirb = 0xff
    mcp02.gppua = 0x00
    mcp02.gppub = 0x00
    # setting address pins (A0-A15):
    mcp00.iodira = 0x00
    mcp00.iodirb = 0x00
    mcp00.gpioa = 0x00
    mcp00.gpiob = 0x00
    mcp00.gppua = 0x00
    mcp00.gppub = 0x00
    # setting address pins (A16-A23):
    mcp01.iodira = 0x00
    mcp01.gpioa = 0x00
    mcp01.gppua = 0x00
    # setting control pins (/CE, /WE, /OE):
    # bit 0 = /CE
    # bit 1 = /WE
    # bit 2 = /OE
    mcp01.iodirb = 0x00
    mcp01.gpiob = 0x07
    pinCE = mcp01.get_pin(8)
    pinWE = mcp01.get_pin(9)
    pinOE = mcp01.get_pin(10)
    pinCE.pull = digitalio.Pull.UP
    pinWE.pull = digitalio.Pull.UP
    pinOE.pull = digitalio.Pull.UP
    pinCE.value = True
    pinWE.value = True
    pinOE.value = True
    def _CE(en):
        if (en == True):
            pinCE.value = False
        elif (en == False):
            pinCE.value = True
            raise Exception("True or False only!")
    def _OE(en):
        if (en == True):
            pinOE.value = False
        elif (en == False):
            pinOE.value = True
            raise Exception("True or False only!")
    def putAddr(addr):
        mcp00.gpioa = (addr & 0x000000ff)
        mcp00.gpiob = (addr & 0x0000ff00) >> 8
        mcp01.gpioa = (addr & 0x00ff0000) >> 16
        #print("mcp00 gpioa = " + hex(mcp00.gpioa))
        #print("mcp00 gpiob = " + hex(mcp00.gpiob))
        #print("mcp01 gpioa = " + hex(mcp01.gpioa))
    def getData():
        dataL = mcp02.gpioa
        dataH = mcp02.gpiob
        return (dataH << 8) | dataL
    def readAddr(addr):
        value = None
        value = getData()
        return value
    def dumpROM():
        for addr in range(0x800000, 0xffffff,1):
            print("Reading block: ", hex(addr))
            f.write(readAddr(addr).to_bytes(2, byteorder="little"))   
    f = open("romdump.hex","wb")
    # possibly read only 8 megabits!
    #f.write(readAddr(0).to_bytes(2, byteorder="big"))
    startTime =
    addr = 0
    #f.write(readAddr(addr).to_bytes(2, byteorder="big"))
    # let's read each 2048 blocks first!
    stopTime =
    print("time taken: ", stopTime-startTime)

    What's next? I'm trying to understand how the menu and the Aaronix Test screen works. I suspect this had to do a initial startup on the LCD and possibly some other peripherals.

  • Attempt no.2 : New information!

    NYH-workshop01/25/2023 at 12:52 0 comments

    Yes, it has been a very long time since I updated here due to the lack of information on these little things.

    Previously, I have only managed to get a partial dump of the ROM - possibly only the first 8 megabytes.

    However, someone on the 'net has managed to upload another schematic of the ROM carrier board - this time there's a slight variation on the A22 and A23 pin which I couldn't locate earlier:

    (Thanks to the person who uploaded this - I couldn't find this link anymore!)

    I took out that dumper board which I made it using the Raspberry Pi and some MCP23017s since 2020 and tried to reconnect the A22 and A23. However, the dumping is pretty slow and could take a day or so, and as a little preview I managed to see some menu cut-outs and game titles inside (I dumped from 0x80000 onwards). I believe that it has a menu in Mandarin too:

    And I found a list of game using the HxD too:

    Earlier in 2022, someone examined the ROM dump and uploaded it into a forum, however these dumps couldn't be downloaded, it's a broken link instead:

    Not only the person had dumped it but he/she had possibly get it to work using the EmuVT emulator:

    Also, there are a number of videos that is showing the unit being modified to play other compilation of games:

    There are no schematics provided or instructions posted in these videos, so if there are any new information on these, you can put in the comments below! :D

  • What a big dump! Analysis no. 1!

    NYH-workshop11/29/2020 at 06:14 0 comments

    Pardon me for that title. The dump means I dumped that 8 Megabytes worth of contents from that ROM I described earlier.

    After a few more hours of dumping through Raspberry Pi and extracted its BIN file, I noticed that:

    • Suspected inconsistent addressing beyond 64KB
      • I peeked into the original snapshot of the bootup from the bus analyzer from Analog Discovery 2:
      • Then, in the same fashion, I sniffed out the last 8-bit of the address from the bus analyzer: 

      • The top 8-bit address during the bootup shows a 0x02 and 0x03 - but I couldn't find that exact bootup code from above with that higher address in the BIN file. That leads to...

    • Incomplete memory dump
      • This BIN sample has been analyzed by an experienced member in BGC forum:
      • It is incomplete - I looked high and low for the menu cut-outs and hints of it but couldn't see them.
      • Highly suspected that the last address A24 isn't accessible - it ends up mirroring whatever contents from the first 8MB.

    I have another sample of this and planning to extract and see if these are the same thing or not.

View all 17 project logs

Enjoy this project?



e64 wrote 04/05/2024 at 12:18 point

one small questions. Is possible replace cpu to arm cortex-m or raspberry pi pico

  Are you sure? yes | no

NYH-workshop wrote 04/11/2024 at 03:34 point

Hi, it is possible - you may need to replace the entire circuit board with your own microcontroller. There is someone who actually created a custom PCB to fit inside the handheld. However, this is beyond the scope of the discussion. :D

  Are you sure? yes | no

e64 wrote 04/11/2024 at 20:20 point

Yes, this is beyond discussion. I thought it would be a simpler way to use the whole board, display, power supply but replacing it with a known cpu

You are planing runing fuzix on this dev?

  Are you sure? yes | no

Breyos wrote 10/14/2023 at 05:24 point

I found one of these things at Walmart, and thought it looked interesting enough to crack open and take a look inside! Mine came with one of the button contacts missing, so I couldn't "right" in any of the games. I was hoping to maybe replace the microcontroller inside, but I had no idea it would essentially be a NES emulator!

  Are you sure? yes | no

NYH-workshop wrote 04/11/2024 at 03:35 point

Apologies for the late reply - it's not an NES emulator, but it is a heavily modified Famiclone on a Chip. This one possibly uses a VT-02 or VT-03 ones as it can run using the EmuVT emulator.

  Are you sure? yes | no

fdd wrote 03/29/2023 at 16:09 point

Hi, I love your project!, I wonder if there is some place to download a full dump of memory to test it in the emulator. Links in 4pda forum are broken. Regards

  Are you sure? yes | no

Starhawk wrote 10/17/2020 at 17:20 point

Re 16bit "6502" CPUs... look up the 65C816 from Western Design Co aka WDC ;) 6502[dot]org may or may not have the data sheet, along with that of their 65C02 (which is slightly different from the more common Rockwell/etc versions)... can't remember. But WDC (not the same WDC as the one that makes hard drives and SSDs, obviously!) publishes their own datasheets, if nobody else does... ;)

  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