Yamaha v6355
17/01/2026
17/01/2026 (Minor update)
(This is an incomplete page, to be updated later)
The Yamaha v6355 is a CGA video chip, usually connected to 16K of video RAM, which has a few limitations as well as a few extra features.
It's used in a number of PC-compatible systems and cards. The Olivetti Prodest PC 1, the Zenith Data Systems SupersPort and Z-180, the Spectravideo SVI-838 (aka X'press 16 or Barq AQ-900), the ACV-1030 CGA video card, and some other generic CGA video cards.
Features:
It has its own set of special registers, providing extra features.
It can output to a CGA TTL monitor. It displays the usual CGA video modes (including the low and high intensity palettes as well as the CGA "third palette" of black/cyan/red/white, but excluding tweaked text modes) at 50hz or 60hz (if your monitor supports this), in 192, 200, or 204 lines, but can also display a low-res 160x200x16 colour graphics mode. Additionally, it can set the video mode to be 256/512 pixels wide instead of the usual 320/640, and has a single 16x16 hardware sprite that is intended to be used as a cursor or mouse pointer. It does not show any "snow" when writing to video RAM outside of the blanking periods.
It can output to analogue RGB (and composite video, if the circuit is included in the system). It can display the same video modes (at 50hz or 60hz) as the CGA TTL monitor, as well as redefine the palette colours using a 9-bit palette (3 bits per R, G, and B - similar to the MSX 2, Atari ST, and Sega Mega Drive/Genesis). The "third palette" of CGA always shows up as monochrome by this output method.
It can output to an MDA mono monitor, with a very non-standard 200-line image, with an 8x8 font.
WARNING: I don't recommend using an IBM 5151 monitor with this, or any other early MDA monitor that cannot handle being "out-of-sync". The ACV-1030 manual provides a listing to create a COM file that switches the video card into mono mode (which you may place in your AUTOEXEC.BAT file) but that means you are running with CGA timings for, perhaps, 30 seconds while your PC boots up. This is potentially very bad for those old monitors. The ACV-1030 manual also recommends using a "dual-frequency mono monitor" for this mode (meaning 15.6 Khz and 18.432 Khz horizontal frequencies, in this case), and I think that is a sensible suggestion.
It can also output to a 64-line LCD screen (details unknown).
A 64K Configuration?
Some documents suggest that the Yamaha v6355 can be connected to 64K of video RAM (but the v6355 only has the equivalent of 14 address lines, allowing 16K) and can display a 640x200x16 colour graphics mode. However, I am not aware of any system that does this and it is not clear how this video mode would be addressed.
The Z-180 manual loosely describes a "page mode" where four 16K pages are used (DRAM only, not SRAM) and (somehow) the four pages are selected by three bits in the Display Page register. It also says:
640 x 200 Color Graphics - In this graphics submode each pixel may be selected to one of sixteen different colors. A four-bit color code is supplied by external shift registers that correspond to the R, G, B, and I video signals. Additional memory and support logic can also be used in this mode.
The SupersPort manual (80C88 model) says:
640 x 200 Color Graphics - This mode is not implemented, even though the controller will support this mode, because it requires additional video memory and support logic.
The Yamaha v6355 datasheet is available, but it has very limited information. It says it is "Capable of displaying 16 colors in 640 x 204 by using external circuits" and describes pins GD0-GD3 as being "Graphic Data (input)" in 640x200 Color mode. Pins GD1-GD3 are named RA0-RA2 in other modes. (For Yamaha products of that era, it seems that the "Application Manual" is more detailed, but this has not been found for the v6355).
Limitations:
Not all of the CGA registers are implemented. In particular, most of the CRTC registers are not implemented, so CGA text mode cannot be redefined to create semi-graphics.
The palette registers have no effect on the CGA TTL output at all. If the system you're using can output to both monitor types, then you will need to choose your palette carefully or have two sets of graphics.
The ACV-1030 does output colour over the composite connector, but there seems to be an issue with the composite circuit, where the output is at least twice as bright as it should be. This is why the composite palette is either very pale or a brilliant white. (But this can be patched: Composite CGA)
The BIOS on a PC usually does not support text output to the 160x200x16 colour graphics mode but the addressing is basically the same, so it's possible to hook the BIOS routines to write a chunky 4x8 pixel font.
It's unclear whether it's possible to read the Yamaha v6355's special registers. Tests on the ACV-1030 show that it doesn't return any values.
Olivetti Prodest PC 1
The Olivetti Prodest PC 1 has 16K of Video RAM (DRAM) and can output to CGA TTL or analogue RGB. It has a composite video output, but this is monochrome only.
Zenith Data Systems SupersPort and Z-180
The SupersPort laptop has 16K of Video RAM (SRAM), a built-in monochrome LCD screen (with 8 grey levels), and a 9-pin CGA TTL output (so you won't get to see the redefined colour palette) but the manual does provide detailed documentation on the chip. (The SupersPort 286 Model 40 claims to have 64K of Video RAM, but a motherboard listed on eBay has a v6366 in it! The only manual available is for an earlier 80C88 model, which definitely uses a v6355 and 16K).
The Z-180 laptop has 16K of Video RAM, a built-in monochrome LCD screen (with ? grey levels), a monochrome composite output, and a 9-pin CGA TTL output (so you won't see the palette here either). Again, the manual provides detailed documentation on the chip.
Spectravideo SVI-838
The Spectravideo SVI-838 / X'press 16 / Barq AQ-900 have 16K of Video RAM can output to analogue RGB or TTL RGB. It has two video chips and overlays the Yamaha v6355 video output on top of the Yamaha V9938 video output.
ACV-1030 CGA card
The ACV-1030 is a 16K CGA clone card (for DOS PCs) that was easily available on online marketplaces up until about November 2025.
As well as the usual 9-pin CGA/MDA monitor connector, it has a composite video output which can use the redefined palette colours. If connected to an NTSC-compatible composite monitor/TV (and if the output is set to 60hz mode) it can display the "CGA Composite Color" mode, using the IBM PCjr palette.
Due to an issue with the composite circuit, the palette is extremely desaturated. If you treat the palette as being 6-bit (2 bits for each of R, G, and B) and only use the lower values then you can see the correct colours, albeit in a more limited fashion (but still equal to the EGA palette).
Other Generic Yamaha v6355 CGA cards
These are still available and have 16K of Video RAM, but they don't have any analogue output, so redefining the palette has no effect.
Setting the Yamaha v6355's special registers
There is an address space of 128 special registers (although not all of them are used), these are accessed via I/O.
To write to the special registers, you first need to select the register index, like so:
outp(0x03DD, index);
NOTE: If you wish to use the 16-colour mode, every write to 0x03DD must set bit 7 of the register index.
Then output the data like so:
outp(0x03DE, data);
Trying to reading the data back does not appear to work (at least on the ACV-1030).
Whenever you write to 0x03DE, the register index auto-increments.
(Complete list to be updated later)
The palette uses indexes 0x40-0x5F.
0x40 COL00 00000RRR
0x41 COL00 0GGG0BBB
0x42 COL01 00000RRR
0x43 COL01 0GGG0BBB
0x44 COL02 00000RRR
0x45 COL02 0GGG0BBB
0x46 COL03 00000RRR
0x47 COL03 0GGG0BBB
0x48 COL04 00000RRR
0x49 COL04 0GGG0BBB
0x4A COL05 00000RRR
0x4B COL05 0GGG0BBB
0x4C COL06 00000RRR
0x4D COL06 0GGG0BBB
0x4E COL07 00000RRR
0x4F COL07 0GGG0BBB
0x50 COL08 00000RRR
0x51 COL08 0GGG0BBB
0x52 COL09 00000RRR
0x53 COL09 0GGG0BBB
0x54 COL10 00000RRR
0x55 COL10 0GGG0BBB
0x56 COL11 00000RRR
0x57 COL11 0GGG0BBB
0x58 COL12 00000RRR
0x59 COL12 0GGG0BBB
0x5A COL13 00000RRR
0x5B COL13 0GGG0BBB
0x5C COL14 00000RRR
0x5D COL14 0GGG0BBB
0x5E COL15 00000RRR
0x5F COL15 0GGG0BBB
Example Programs
Y6TEST01 - Lets you test the Yamaha v6355 registers.
V6355 - A simpler piece of software that displays 160x200x16 mode with colour bars.
Both were designed with the ACV-1030 video card in mind, but should work in other circumstances. (I don't have any working hardware to test them on just now, so let's hope for the best!)
Source code is provided for use with the Borland C 3.1 compiler.
Incomplete Source (to be finished later)
First, set the standard 320x200x4 graphics mode, then do some I/O to adjust the chip's registers, then set the palette.
The video addressing is the same as standard CGA (namely the base is at B800h:0000h) and the usual "interleaved" row addressing is used. The only difference is that there are two 16-colour pixels packed within a byte, so the address of a pixel is:
address = ((Y / 2) * 80) + ((Y & 1) * 8192) + (X / 2);
The left pixel is stored in the upper four bits (0xF0) and the right pixel is stored in the lower four bits (0x0F).
To tidy up afterwards, simply set the normal video mode that you desire and (possibly) reset the palette.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <dos.h>
#include <conio.h>
typedef unsigned char u8;
typedef signed char s8;
#ifdef __BORLANDC__
typedef unsigned int u16;
typedef signed int s16;
#else
typedef unsigned short u16;
typedef signed short s16;
#endif
typedef unsigned long u32;
typedef signed long s32;
#ifdef __BORLANDC__
u8 far *SCR = (u8 far *)MK_FP(0xB800, 0); // Borland C-style
#else
u8 *SCR = (u8 *)0xB8000; // Watcom C-style
#endif
typedef struct RGBA
{
u8 R, G, B, A;
} RGBA;
static u8 YAMAHA_V6355_bSpecialBit = 0x00; // The top bit of the Address register $03DD
static u8 YAMAHA_V6355_bHalfBright = 0x00; // The ACV-1030 requires palettes be reduced to 2 bits, otherwise there is severe desaturation
static u8 bInitialScreenMode = 0;
// The standard CGA palette colours
static const RGBA RGBI_PAL[16] =
{
{ 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0xAA, 0x00 },
{ 0x00, 0xAA, 0x00, 0x00 },
{ 0x00, 0xAA, 0xAA, 0x00 },
{ 0xAA, 0x00, 0x00, 0x00 },
{ 0xAA, 0x00, 0xAA, 0x00 },
{ 0xAA, 0x55, 0x00, 0x00 },
{ 0xAA, 0xAA, 0xAA, 0x00 },
{ 0x55, 0x55, 0x55, 0x00 },
{ 0x55, 0x55, 0xFF, 0x00 },
{ 0x55, 0xFF, 0x55, 0x00 },
{ 0x55, 0xFF, 0x55, 0x00 },
{ 0xFF, 0x55, 0x55, 0x00 },
{ 0xFF, 0x55, 0xFF, 0x00 },
{ 0xFF, 0xFF, 0x55, 0x00 },
{ 0xFF, 0xFF, 0xFF, 0x00 },
};
void YAMAHA_V6355_SetSpecialMode(u8 bValue)
{
// The top bit to be written to $03DD (1 = allow 160x200x16 mode)
YAMAHA_V6355_bSpecialBit = bValue ? 0x80 : 0x00;
}
// Write to the register
void YAMAHA_V6355_SetCurrentRegister(u8 bValue)
{
// Auto-increments after writing
outp(0x03DE, bValue);
}
// Select the register
void YAMAHA_V6355_SetAddress(u8 bIndex)
{
outp(0x03DD, YAMAHA_V6355_bSpecialBit | (bIndex & 0x7F));
}
// Select and write to the register
void YAMAHA_V6355_SetAddressAndRegister(u8 bIndex, u8 bValue)
{
outp(0x03DD, YAMAHA_V6355_bSpecialBit | (bIndex & 0x7F));
outp(0x03DE, bValue);
}
// Takes 8-bit R, G, and B values
void YAMAHA_V6355_SetPalette(u8 bIndex, u8 R, u8 G, u8 B)
{
u16 wPalette = 0;
// Convert from 8 bits down to 3 bits...
R >>= 5; G >>= 5; B >>= 5;
if(YAMAHA_V6355_bHalfBright)
{
// The ACV-1030 requires palettes be reduced to 2 bits, otherwise there is severe desaturation
R >>= 1; G >>= 1; B >>= 1;
}
YAMAHA_V6355_SetAddress(0x40 | ((bIndex & 0x0F) << 1));
wPalette = (R) | (G << 12) | (B << 8);
YAMAHA_V6355_SetCurrentRegister((u8)wPalette);
YAMAHA_V6355_SetCurrentRegister((u8)(wPalette >> 8));
}
void YAMAHA_V6355_SetupPalette(void)
{
u8 x;
// Set to the initial RGBI values used by CGA, EGA, etc.
for(x = 0; x < 16; x++)
{
YAMAHA_V6355_SetPalette(x, RGBI_PAL[x].R, RGBI_PAL[x].G, RGBI_PAL[x].B);
}
}
u8 HOST_VIDEO_GetVideoMode(void)
{
union REGS R;
R.h.ah = 0x0F;
int386(0x10, &R, &R);
//printf("Current Video Mode: 0x%02X\n", R.h.al);
return R.h.al;
}
u8 HOST_VIDEO_SetVideoMode(u8 mode)
{
union REGS R;
#ifdef __BORLANDC__
R.x.ax = mode;
int86(0x10, &R, &R);
#else
R.w.ax = mode;
int386(0x10, &R, &R);
#endif
//printf("Mode: %2X (Ret = %02X)\n", mode, R.h.al);
// 1 = Success (mode requested == current mode) (not guaranteed to work on all BIOS versions!)
// 0 = Fail
if(mode != HOST_VIDEO_GetVideoMode())
{
return 0;
}
return 1;
}
void HOST_VIDEO_StoreScreenMode(void)
{
bInitialScreenMode = HOST_VIDEO_GetVideoMode();
}
u8 YAMAHA_V6355_InitScreen(void)
{
u8 mode;
u16 x;
union REGS R;
struct SREGS SR;
/*
0x04 = 320x200x4 (palette 0 or palette 1)
0x05 = 320x200x4 ("palette 2")
0x06 = 640x200x2
*/
mode = 0x04;
if(!HOST_VIDEO_SetVideoMode(mode))
{
return 0;
}
// Set special mode bit (it's used to set the default palette at the end of this function)
YAMAHA_V6355_SetSpecialMode(1);
outp(0x03D8, 0x40 | 0x08 | 0x02); // 160x200x16 mode (16 Color Mode (0x40), Enable Screen (0x08), Enable Colour (!0x04), Graphics (0x02))
outp(0x03D9, 0x20 | 0x10 | 0x00); // Set palette 1 (0x20), intensity (bright) (0x10), black border (0x00)
// Set up the default RGBI palette, possibly in halfbright mode (or change this to set up another palette)
YAMAHA_V6355_SetupPalette();
return 1;
}
void YAMAHA_V6355_ReleaseScreen(void)
{
YAMAHA_V6355_SetSpecialMode(0); // Switch back to normal CGA modes
// Restore the default CGA RGBI palette, possibly in halfbright mode
YAMAHA_V6355_SetupPalette();
HOST_VIDEO_SetVideoMode(bInitialScreenMode);
}
int main(int argc, char *param[])
{
HV_StoreScreenMode();
//printf("Current screen mode: 0x%02X\n", bInitialScreenMode);
if(YAMAHA_V6355_InitScreen())
{
// Display testcard
Testcard();
// Wait for key
while(!kbhit());
getch();
// Back to normal
YAMAHA_V6355_ReleaseScreen();
}
return 1;
}
(C) Jane McKay, 2026