TMS9918A video card for the RC2014

Similar projects worth following
This is a TMS9918A-based video card for the RC2014. It allows the RC2014 to produce NTSC composite video using a classic chip from the 1980s. This board can be configured to use the same ports as the MSX, so it's possible to run some MSX software on it unmodified.

The TMS9918A was used in the TI-99/4A, MSX, ColecoVision, original Sega SG-1000. Enhanced derivatives were used in later MSX computers, the Sega Master System, and the Sega Genesis. It's creators coined the term Sprite, and according to one of it's designers, it also influenced the architecture of the PPU in the Nintendo Entertainment System.

This board is based on a circuit described by Tom LeMense for interfacing the TMS9918A with SRAM.  I took his schematics, added the address decoding and laid out the circuit on an RC2014 module.

The TMS9918A data and control ports can map to 98 and 99, respectively, the same as the original MSX. This allows some unmodified MSX programs to run on the RC2014. I have successfully gotten the Bold demo to run. The graphics from other programs should work as well, but other parts of the MSX, such as I/O may need additional hardware to work.

The board has been manufactured using the gerber files attached to the project and is confirmed to work.


Bold MSX Demo

x-zip-compressed - 38.76 kB - 06/29/2018 at 01:11


Gerber files for board manufacture

x-zip-compressed - 43.57 kB - 06/22/2018 at 14:56


  • ColecoVision Games

    J.B. Langston07/08/2018 at 18:33 0 comments

    I have successfully run a few ColecoVision games with only a small modification to the Coleco BIOS in order to change the port used for the TMS9918A and make the maskable interrupt handler redirect to the NMI handler because the ColecoVision uses NMI for the TMS9918A's vblank interrupt, whereas my board uses INT.  

    So far, Donkey Kong and Burger Time are fully playable. For some reason I haven't figured out yet, Donkey Kong Jr hangs after the skill select screen. 

    I'm using a second MCP23S17 I/O expander hooked up to the SPI bus on my z80ctrl board to read the joystick. The z80ctrl reads the joystick value via SPI, and relays the results back to the Z80 over port 0xFC, where the ColecoVision code expects to find them.

    Unfortunately some newer games talked directly to the hardware ports instead of going through the BIOS so I will have to individually patch those games.  I have gotten as far as the title screen in Centipede and Star Wars after patching their ROMs to use the correct video ports.

    None of the games have any sound currently because the ColecoVision uses a TI SN76489 instead of the YM2149 chip that I have in my RC2014.  I may design a SN76489 board for the RC2014, or it might be possible to patch the ROMs to use the YM2149 instead, since both chips had similar capabilities. I haven't researched what all would be involved in doing this yet.

    Inexplicably, I am terrible at all of the games I've played so far. Clearly there is some kind of subtle incompatibility that is making these old games much harder than I remember them. Yeah, that's gotta be what it is.

  • Attention Please

    J.B. Langston07/03/2018 at 14:02 0 comments

    The RC2014's killer app has arrived...

    That is all.

    (And Source code is available.)

  • Build Complete

    J.B. Langston06/22/2018 at 02:22 3 comments

    The printed circuit boards I designed for my video card arrived in the mail today, and I got it put together.

    It works great. The amount of noise in the video signal is vastly reduced, and I no longer have any glitches during memory transfers.  With the board, I have been able to successfully run the Bold MSX demo on my RC2014 with Graphics and Sound, 100% glitch free.

  • MSX Demos on Homebrew Hardware

    J.B. Langston06/20/2018 at 01:35 0 comments

    I've been able to successfully run the Bold demo for the MSX 1 on the RC2014 with my TMS9918A video card. 

    Since I have mapped the TMS9918A's RAM and register ports to 98 and 99, the same as on the MSX, the demo will output video 100% unmodified. Unfortunately there is no audio in the unmodified code because the YM2149 sound card for the RC2014 does not support the port configuration used by the MSX.  With a minor modification, however, It's possible to get sound working.

    Rather than trying to get MSX-DOS to run on the RC2014, which would be a much bigger undertaking, I used my z80ctrl board to load the demo binaries directly from the SD card into memory at origin 100H. The and files were extracted from the bold.dsk image using openMSX with the following console commands:

    virtual_drive bold.dsk
    diskmanipulator export virtual_drive .

    One tiny modification was made to I poked a HALT (76) at address 152 in place of the RET that was there before. This is necessary because there's no other software to return to, so I needed to halt the processor when this part was done so I could load the next part of the demo. was completely unmodified, and was simply loaded at 100H and run after halted.

    To get sound working, I needed to modify the routine in that sends audio commands to the YM2149.  The unmodified version looks like this:

    06fa  0e a0            ..     LD C,A0H
    06fc  21 f9 07         !..    LD HL,07F9H
    06ff  ed 79            .y     OUT (C),A
    0701  0c               .      INC C
    0702  ed a3            ..     OUTI
    0704  0d               .      DEC C
    0705  3c               <      INC A
    0706  fe 0d            ..     CP 0DH
    0708  20 f5             .     JR NZ,-11
    070a  ed 79            .y     OUT (C),A
    070c  7e               ~      LD A,(HL)
    070d  a7               .      AND A
    070e  f8               .      RET M
    070f  0c               .      INC C
    0710  ed 79            .y     OUT (C),A
    0712  c9               .      RET

    Port A0H is the address port, and A1H is the data port used by the MSX for the YM2149.  The demo loads A0H into register c, then uses the out (c), a and outi commands to send data to the chip at the port address stored in c.  It switches c back and forth between A0H and A1H using the inc and dec instructions.  I had to be careful about modifying the code because any change to the length of the instructions would change the offsets of the rest of the program and cause absolute references to those addresses to become invalid. 

    I had initially devised a much more complicated scheme but thanks to neon reminding me that "out (c), a" is a 2 byte instruction, the same as "out (nn), a", I was able to simply replace the "out (c), a" instructions with "out (nn), a" instructions that send data directly to the desired port.  I still had to load c with the data port address to use the outi instruction, but I no longer needed to switch c back and forth between ports, so I changed the inc c/dec c instructions to nops.  The modified version of the code that uses the default D0/D8 ports for the RC2014 YM/AY sound card looks like this:

    06fa  0e d0            ..     LD C,D0H
    06fc  21 f9 07         !..    LD HL,07F9H
    06ff  d3 d8            ..     OUT (D8H),A
    0701  00               .      NOP
    0702  ed a3            ..     OUTI
    0704  00               .      NOP
    0705  3c               <      INC A
    0706  fe 0d            ..     CP 0DH
    0708  20 f5             .     JR NZ,-11
    070a  d3 d8            ..     OUT (D8H),A
    070c  7e               ~      LD A,(HL)
    070d  a7               .      AND A
    070e  f8               .      RET M
    070f  00               .      NOP
    0710  d3 d0            ..     OUT (D0H),A
    0712  c9               .      RET

    I used z80ctrl's scripting facility to load both parts of the demo into memory and then automatically patch and run them.  With this script, it's possible to run the unmodified demo binaries simply by typing "do bold" (assuming the script has been saved in a file called bold and copied to the z80ctrl's SD card along with both and

    page 20
    clkdiv 4
    loadbin 100
    poke 152 76
    run 100
    loadbin 100
    poke 06fb d0
    poke 06ff d3
    poke 0700 d8
    poke 0701 00
    poke 0704 00
    poke 070a...
    Read more »

View all 4 project logs

  • 1
    Visit GitHub

    Visit GitHub for BOM and build tips.

View all instructions

Enjoy this project?



David Kuder wrote 07/01/2018 at 15:08 point

Thanks for the inspiration to make my own TMS9918/AY-3 card for Z-80 STDBUS. I’m also working on a joystick interface that is compatible with the RC2014 AY-3 card aswell.

  Are you sure? yes | no

J.B. Langston wrote 07/01/2018 at 15:42 point

Cool! Let me know once you have details about the project posted. I am actually trying to get some ColecoVision games running on the RC2014 so that Joystick interface would be very handy. (See thread here:!topic/rc2014-z80/d1iM0UVwYU8)

  Are you sure? yes | no

David Kuder wrote 07/02/2018 at 01:44 point

I've got a first attempt up here:

GPEX*.zip is the adapter for MSX pinout joysticks.

For Atari joysticks you would need to swap a few pins around.

Additionally, some bodge resistors are likely to be necessary to pull the data lines high when buttons aren't being pressed.

  Are you sure? yes | no

J.B. Langston wrote 07/08/2018 at 23:21 point

For my ColecoVision project, I ended up building a joystick adapter out of a MCP23S17 I/O expander and having the z80ctrl board pass along the values via the expected port for the Colecovision.  I posted a few more details about it in a project log today.

  Are you sure? yes | no

David Kuder wrote 07/09/2018 at 18:41 point

Nice,  I got my boards in and have been working on getting all the chips together.  I'm hopeful that the 10.7MHz crystal will be in before this weekend so I can fire mine up without having to resort to using a signal generator.  The MSX gamepad interface boards are in and I'll assemble one of them when I get a hold of a PSG chip.

  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