# Mac-SE video

## Macintosh SE Video interface

Rather than let an old Mac SE with dead drives go to waste, I built a video card interface to the BeagleBone Black to drive the 512x342x1 display using the PRU. The bit clock is 16 MHz, about 64ns per bit, which is easily doable with programmable realtime unit, but not from userspace due to the hard realtime constraints -- a few nanosecond delay in generating the video signal causes visible distortion. The source is github.com/osresearch/classicmac and reuses the PRU interface from LEDscape / Octoscroller. See it in action!

# X11 and USB input

When using the PRU based framebuffer, Xvfb can be used to create a user-space to user-space X server that creates a virtual frame buffer in /tmp:

Xvfb :0 -ac -screen 0 512x384x8 -fbdir /tmp/ -retro


This XWD format file is the translated into the 1-bit output with the XWD to PRU translation program:

./x11mac /tmp/Xvfb_screen0


Since Xvfb doesn't read from the USB ports, I had to write something to translate Linux event devices files into synthetic X events using the XTest framework. Run the mouse/keyboard event to X11 event translation:

./eventmap /dev/input/event*


You will probably want to use something like my ADB to USB adapter to allow classic Apple keyboards and mice to work with the USB input.

# Using the LVDS framer

Instead of using the PRU, it looks like fbcons and X are able to use the tilcdc device to drive the LCD pins instead with the addition of a NAND gate to both invert the video line and pull it high (idle) when the hsync is low (active). Configuring the HDMI/LVDS framer requires a special DeviceTree file, cape-bone-mac.dts, and doesn't properly handle the negative backporch timing. This causes some distortion on the right-hand side of the screen, but allows an unmodified X11 to be used. This also means that Linux console output can be sent to the CRT.

Load the Device Tree overlay with:

cd classicmac
make firmware


And setup /etc/X11/xorg.conf; unfortunately this uses an 32-bit TrueColor visual, which doesn't do the cool 1-bit dithering. Not sure how to fix this yet.

Section "Device"
Identifier	"Frame Buffer"
Driver		"fbdev"
EndSection


The video output pin should be setup as NAND(VIDEO,NAND(!HSYNC,!VSYNC)) to pull the video pin high if either !HSYNC or !VSYNC were asserted. Since the video port is 16 bits wide there are 5 red, 6 green and 5 blue pins -- you will want to use a MSB from one of these for the 1-bit video.

# Wiring

Based on this schematic, the pins on Mac SE motherboard J12 are:

Pin Color Function
1 Black GND
2 Black GND
3 Black GND
4 Black GND
5 Black GND
6 Blue -5V DC
7 Green -12V DC
8 Black GND
9 White VIDEO (starts 11.2 usec after falling edge of HSYNC, lasts about 33 usec, first data line is 1.26ms after falling edge of VSYNC)
10 Purple HSYNC (square wave, falling edge triggered, 45 usec per line)
11 Gray VSYNC (square wave, falling edge triggered, 60.10 Hz / 16.64 ms per frame, 180 usec low)
12 Orange +5V DC
13 Orange +5V DC
14 Yellow +12V DC

Since the pins immediately go through NAND gates (74LS78), it is not necessary to level shift from the 3V output from the BBB to the 5V used by the Mac. The powersupply for the monitor produces a clean 5V that can run the BBB once things are setup. Only need three pins from the PRU (video, hsync and vsync), leaving plenty for an eventual ADB port.

# Timing

Falling edge of VSYNC triggers vertical blanking and start of a new frame. VSYNC falling edge to rising edge: 180 usec. HSYNC pulses continue during vertical blanking, offset 8 usec from the falling edge of VSYNC. HSYNC pulse falling edge to falling-edge is about 45 usec.

Falling edge triggers vertical blanking and start of a new frame. VSYNC falling edge to rising edge: 180 usec. VIDEO pulses begin after 1.26 ms. HSYNC pulses continue during this time, too.

HSYNC is falling edge triggered, 45 usec between edges. Rising edge occurs 18.4 usec after falling edge. Video data begins 11.2 usec after falling edge. Roughly 16 MHz dotclock (512 pulses in 32 usec). The "hsync backporch" is negative, which doesn't seem possible with BeagleBone's LVDS framer.