Sanyo MBC-555

Repair story by Mike @ Leaded Solder tip:

black & white ordered dithering

;from dark to light: 4x8 bits (4 lines, 8 bits per line). in total 8 chars.
grays: db 0,0,0,0, 136,0,34,0, 170,0,170,0, 170,17,170,68, 170,85,170,85, 85,238,85,187, 119,255,221,255, 255,255,255,255

3 bit grayscale dithering on monochrome monitor

PImage img = loadImage("input/"+filename);
img.resize(width, 200);
img = applyDithering(img, 8); //8 levels of brightness
img = grayTo3bitIntensity(img);
savePIC(img, "data/output/"+filename.replace(".jpg", ".pic"));
void savePIC(PImage img, String filename) {
  byte bytes[] = new byte[img.width*img.height*3/8+4];
  bytes[0] = byte(img.width & 255);
  bytes[1] = byte(img.width >> 8);
  bytes[2] = byte(img.height & 255);
  bytes[3] = byte(img.height >> 8);

  for (int i=0, x=0, y=0, n=img.width*img.height/8; i<n; i++) {
    for (int j=128; j>0; j/=2, x=(x+1)%img.width, y=i/(img.width/8)) {
      color c = img.get(x, y);
      bytes[i+4+2*n] |= byte(j * red(c)/255);
      bytes[i+4+1*n] |= byte(j * green(c)/255);
      bytes[i+4+0*n] |= byte(j * blue(c)/255);
  saveBytes(filename, bytes);

PImage grayTo3bitIntensity(PImage img) {
  PImage img2 = img.get();
  color c[] = {color(0), color(0,0,255),color(0,255,0),color(0,255,255),color(255,0,0),color(255,0,255),color(255,255,0),color(255,255,255)};
  int lut[] = {0,1,4,2,5,3,6,7};
  for (int y = 0; y<img.height; y++) {
    for (int x = 0; x<img.width; x++) {
      int index = int(brightness(img.pixels[y*img.width+x])/32); //32=256/8 because 8 colors in 3 bit
  return img2;

Panel mounted switches for diskimage and drive selection


Screenshot 2022-09-16 at 12 12 41

run Mame for Sanyo MBC-555

  • ROM in roms/mbc55x/mbc55x-v120.rom
  • Fn+DEL (to enable UI interface controls) then TAB to show menu
  • make mame for (just) Sanyo: make SUBTARGET=mbc55xtest SOURCE=src/mame/sanyo/mbc55x.cpp
  • make mame tools: make TOOLS=1 REGENIE=1
    ./mbc55xtest mbc55x -ramsize 256K -verbose -skip_gameinfo -effect scanlines -window -nomaximize -resolution0 800x600 -flop1 floppies/disk-a.img

BASIC CALL function

BASIC manual Sanyo MBC-555

decode Michtron PIC image file with Processing


//load and check width
byte bytes[] = loadBytes("SATURN.PIC");
int w = (bytes[1]<<8) + (bytes[0] & 0xff);
int h = (bytes[3]<<8) + (bytes[2] & 0xff);

//check and fix width if needed
//int bytesPerChannel = (bytes.length-4)/3;
//if (w*h/8<bytesPerChannel) 
//  w = (int(w+8)/8)*8;

for (int i=0, x=0, y=0, n=w*h/8; i<n; i++) {
  for (int j=128; j>0; j/=2, x=(x+1)%w, y=i/(w/8)) {
    int rr=(bytes[i+2*n+4]&j)/j<<8;
    int gg=(bytes[i+1*n+4]&j)/j<<8;
    int bb=(bytes[i+0*n+4]&j)/j<<8;
    fill(rr, gg, bb);
    rect(x, y*2, 1, 1.75); //double height, with slight vertical raster line in between the lines



receive data from Python

on Sanyo: type file.asm > aux

#!/usr/bin/env python3

import serial

ser = serial.Serial('/dev/tty.usbmodem1301',1200)

while True:
    x =
    print(x.decode('ascii'), end="")


sanyo mbc-555 VRAM emulation in Processing/Java

(running in 72 cols mode, update to 80 = 640px if needed)

PImage getVRAM() {
  PImage img = createImage(576, 200, RGB);
  for (int y=0, bit=0, j=0; y<img.height; y++) {
    for (int x=0; x<img.width; x++, bit=128>>(x%8), j++) {
      int i=int(y/4)*img.width/2+(y%4)+int(x/8)*4;
      int r = (mem[RED+i] & bit)>0 ? 255 : 0;
      int g = (mem[GREEN+i] & bit)>0 ? 255 : 0;
      int b = (mem[BLUE+i] & bit)>0 ? 255 : 0;
      img.pixels[j] = color(r, g, b);
  return img;


A tribute to Martin Kleppe's beautiful as well as a tribute to the Sanyo MBC-550/555 PC (1984) which forced me to be creative with code since 1994.

My own emulator and bootsector experiments


segments and offsets

"The 8086 has 20-bit addressing, but only 16-bit registers. To generate 20-bit addresses, it combines a segment with an offset. " SEGMENT*16+OFFSET


not for Sanyo but emulator for x86 in general: On Mac:

brew install qemu
qemu-system-x86_64 -fda boot-basic.img


nog onderzoeken:


-l 100 1 0 1  # load onto address 100h from 2nd drive (1) the first sector (0) and only one sector
writing 0200h bytes (512 bytes)

interrupt controller info

Sanyo MBC550 - John Elliott 27 January 2016

int 14h Serial, int 16h keyboard etc

ms-dos int services

debug search

debug basic.exe
s 1c67:ffff ffff e4 18   # searches for the bytes e4 and 18

Time Bandit BANDIT.EXE crack

this is a first step. Skipping disk access at start.

-g 8ee8
-g =8ef3

samdisk (samdisk-388-osx works on Macbook Air M1)

./samdisk IMAGE.td0  /Volumes/FLASHFLOPPY/IMAGE.dsk


Goed nieuws! Gotek met FlashFloppy firmware werkt super op de Sanyo MBC-555.

# in FF.CFG 
interface = shugart
host = pc-dos
pin02 = auto
pin34 = auto
nav-mode = indexed   # voor 0001-msdos211.img etc
indexed-prefix = ""


  • wellicht deze bestellen: (nee niet, mailcontact gehad. Werkt alleen voor 1.2MB diskdrives, en dan ook nog eens readonly.)


  • Capacitor C9 on the board may need to be dealt with if disk access is slow or erratic (it was installed backwards at the factory)."


  • "The PC floppy cable (assuming that you don't have any drives with a READY/ line on pin 34) can be a bit problematical to fabricate. On the other hand, if you can find a Teac FD235HF with the appropriate jumpers or a FD235F (which does have a READY/ line), you're in business, sort of." [[|source]]

  • see [[disk]]

  • index sensor measures optically the hole in the floppy disk. It marks the start of the current track. Read 'index sensor adjustment' in Sams Computer Facts about the Sanyo. I measure 208ms (milliseconds) for one turn of the disk. Around 5 turns a second and 300 turns per minute. Which is right according to 'spindle speed adjustment' part.

  • Weird thing: when I remove the index sensor this has no effect on the readings on TP9 and TP10. There's 10us between the pulses.

  • 'Precompensation adjustment': Connect input of a scope to TP1 on System Board. Set scope sweep to 1uSec, voltage to 2V and trigger to positive slope. Adjust Precompensation Control (RV1) for 2uSec from the rising edge of the first pulse to the rising edge of the second pulse. RESULT: 2uSec 500kHz.


Als een diskette bad sectors heeft kun je geen DISKCOPY gebruiken. Je kunt in veel gevallen wel met COPY de bestanden overzetten. Eventueel kun je met DEBUG de sectors 1 voor laden en wegschrijven (l 0 0 5 1 -> w 0 0 0 5 1).

Info about segments:offsets

Test pins on mainboard

  • TP1: Precompensation adjustment test. Should measure 2 uSec / 500 kHz. Adjust RV1 to fix.
  • TP2: ??

Drive Track Program

The following Basic program can be used to select Driva A or B, select side 0 or 1 and step the Drive Head to a specific track. To stop the program, press the BREAK key.

30 IF S=0 THEN Y=0 ELSE Y=4
40 IF D$="A" THEN Z=0 ELSE Z=1
50 TS=0: OUT 28, Y+Z: OUT 8,8
60 FOR D=1 TO 500: NEXT D
80 IF T>40 THEN 70
100 IF T>TS THEN C=72 ELSE C=104
110 FOR X=1 TO TR
120 OUT 8,C
130 FOR D=1 TO 5: NEXT D
140 NEXT X: TS=T
160 A$=INKEY$: OUT 8,228: IF A$="" THEN 160 ELSE 70


1l  # list from line one
1   # edit line 1
5i  # insert line(s) before line 5
q   # exit without saving
e   # save and exit
edlin autoexec.bat
  line of text

wordstar manual

  • fill memory with 0's: e 0 ffff 0
  • rcx sets cx register. This register is used in to store the amount of bytes to write to the loaded (or newly created file).
  • l 0 0 5 1 load sector 5 of drive 0 at currentSeg:0000

create a program with (ms-dos 1.25 without assemble command)

A> debug
- e 100
  B8 {space} 00 {space} 4C {space} CD {space} 21 {enter}
0AAC:0100 B8004C    MOV    AX,4C00
0AAC:0103 CD21      INT    21
-n filename

more info about Debug:

technical info

Game I/O

    Apple II Game I/O Connector
    This 16-pin DIP socket is described in the Apple II Reference
    Manual (January 1978) as "a means of connecting paddle controls,
    lights and switches to the APPLE II for use in controlling video
    games, etc." The connector provides for four analog "paddle"
    input signals (0-150KΩ resistance) which are converted to
    digital pulses by a NE558 quad timer on the main board. The
    connector also provides several digital switch inputs and
    "annunciator" outputs, all LS/TTL compatible. Apple joysticks
    provide active high switches (though at least one third-party
    product treats them as active low) and Apple main boards have no
    pullups on these inputs, which thus read 0 if disconnected.
    While pins 9 and 16 are unconnected on the Apple II, they provide
    additional digital output and input pins respectively on the Sanyo
    MBC-550/555 (which uses 74LS123 monostables instead of a NE558).
    The Apple IIgs also recognizes a switch input 3, though this is
    placed on pin 9 of the internal connector rather than 16.
                   +5V   1 |*           | 16  (SW3)
                   SW0   2 |            | 15  AN0
                   SW1   3 |            | 14  AN1
                   SW2   4 |            | 13  AN2
                  /STB   5 |  GAME I/O  | 12  AN3
                  PDL0   6 |            | 11  PDL3
                  PDL2   7 |            | 10  PDL1
                   GND   8 |            |  9  (AN4/SW3)