Introduction: Hacking a Brother CRT Word Processor With an ESP32
As the original device was very limited, but really cool looking with that ultra wide yellow CRT, I set out to make it fully programmable. What I did was reverse engineer the CRT signals, which are TTL digital video, and the custom keyboard matrix. I used a Teensy Arduino with custom software to scan and output serial and a TTGO VGA32 (ESP32) as the main controller. I had to bypass the array network to get a TTL video signal out along with H and V sync. There is no info so it was trial, error and calculations. But now I’m at a point where I can type on screen and have full bitmap control of the 400x240 display using the fabgl library. I don’t see any examples of people doing what I did (driving a TTL CRT). This could also be applied to drive and MDA display making it more useful than just for text.
Video of my project
https://youtu.be/mr3uRO7FDz8?si=IAot_xc7iEtRvjL9
Article:
https://hackaday.com/2025/09/09/o-brother-what-art-thou/
Brother WP2200 ROM: https://drive.google.com/file/d/1E6CxmteOEff3cIqknGAPqS7bwkX5eZxv/view?usp=sharing
Brother WP2200 Fonts (fabgl headers): https://drive.google.com/file/d/1hRXDGrS9TexxG24WPeHtWgdHc6Ln5a1g/view?usp=drive_link
WARNING: Working with a CRT is dangerous and if you don't know what you are doing, you can get hurt or killed. This instructable is for information and I am not responsible if something happens to you. Familiarize yourself with safely working on CRT circuitry and tubes. You need to take measurements while the unit is powered on, and if not comfortable with that... don't proceed.
Supplies
VGA32 Board: https://lilygo.cc/en-ca/products/fabgl-vga32?srsltid=AfmBOorSKwJO1NzpQkR-jDcaac3g34hN3DW2GBzn85onc_84qqU21l7O
Teensy LC: https://www.pjrc.com/teensy/teensyLC.html (as a keyboard matrix decoder. Not covered here)
Espressif ESP32 library 2.0.17. You can not use a newer version!
Fabgl library documentation: http://www.fabglib.org/index.html
Fabgl GitHub: https://github.com/fdivitto/FabGL
Thank you to Fabrizio Di Vittorio for making this possible with your awesome library!
Step 1: Introducing the Brother WP-2200
This word processor comes from a line of very similar units dating back to the 80s such as the WP-55. As far as I can tell, the general specifications didn’t change much, nor did the software, but advances in electronics allowed them to build it cheaper. My model, which is from 1992 has a very cheap, single sided PCB with many of the peripheral logic built into a mystery ASIC. The unit contains a daisy wheel printer and 3.5" floppy drive. The specs are:
CPU: HD64180 (Z80+MMU)
RAM: 64kB
ROM: 1MB
I/O: Keyboard
Amber Monochrome TTL CRT 720x240 @ 60Hz
I dumped the ROM and disassembled it, for anyone interested. It would have all been coded in Assembly. There are plenty of videos and websites that describe these units so I’ll leave that out. What I will note is that besides the building software, it is known to run a spreadsheet program via floppy and some supported a Brother port of Tetris. Although have only seen it on LCD models and not CRT. Besides built in displays, some had external MDA monitor support.
As I couldn’t really understand how the original code worked, nor did I have a service manual or know what is going on in the ASIC, I thought the best I could do to bend the monitor and keyboard to my will was to introduce my own microcontroller and remove the original board. The first thing I had to find out was if it was practical to drive the monitor, and how I could do it. If I couldn’t get that, the project wasn’t worth it for me.
Step 2: Reverse Engineering the CRT Signals
After previously playing with an MDA whose video cable was cut off, I learned about TTL video signals. How just with H Sync, V Sync, on/off video signal (not analog) and “bright”. Judging by the look of the Brother CRT, and knowing that other models used MDA compatible monitors, I figured this one was probably MDA as well. With my oscilloscope, I found that wasn’t the case. It was close, but not close enough. But it made sense considering this was a “half height” display.
Leaving the CRT connector connected to the motherboard and inserting my oscilloscope probe into each pin I was able to find:
- 16.22kHz which must be H Sync
- 60Hz which must be V Sync
- And another square wave signal with varying frequency which figured must be video.
- One pin was ground as verified with my multi meter, and the shield around the video wire went to another pin common with ground.
- In this case there was no "bright" or "intensity" line. Just the 5 pins total.
Unfortunately this means I couldn’t use an old dos pc with an MDA card to drive it. But then I remembered I had a TTGO VGA32. This little ESP32 variant provides a perfect VGA signal with the Fabgl library and supports a bunch of cool emulators, games and other applications as library examples. If only I could use it for TTL video, this would be perfect! The Sync pins of VGA are already TTL, I just had to worry about video.
So I found the schematic for the board online and discovered the analog video was created using a resistor ladder method. 2 gpio pins per colour (R,G, &B) going through resistors which then go to a single colour pin out. I desoldered the resistors and removed them (desolder) for one colour. Red I then ran a wire from that pin to one of the free gpio pins on the header (gpio 12).
Step 3: Setting Up the Software
This video from the creator of the Fabgl library explains the software setup well: https://youtu.be/8OTaPQlSTas?si=PyG9-1Mt6IzNjC2L
Step 4: Modifying a Sketch to Include Custom CRT Timing
So now this is where I brought in my friends Chat GPT and Claude. I didn’t know how to calculate CRT timing values so I used the tools. Making measurements with the scope, and entering the values. Trying one thing after another, I came down to the values that would generate at least the proper sync frequencies. Before hooking anything up, I made sure I had sync frequencies that exactly matched the original board. Then I felt confident to connect to the CRT. Although the original board was true 5v TTL, the VGA32 supplies 3.3v output. This turned out to be no problem. The threshold of high state must be around 2v or so.
The following values ended up being what worked:
14.31818
- Dot clock frequency in MHz (14.31818 MHz).
- Determines how fast pixels are shifted out. Every "pixel" on the line is one tick of this clock.
- Fun fact: 14.31818 MHz is a classic NTSC colorburst multiple (4×3.579545 MHz), very common in 80s/90s video hardware.
Horizontal section
- 720 = HDisplay (active/visible pixels per line).
- 736 = HSyncStart (where the horizontal sync pulse begins, in pixel clocks from line start).
- 776 = HSyncEnd (where the horizontal sync pulse ends).
- 880 = HTotal (total pixels per line, including blanking and sync).
- Line time = HTotal ÷ DotClock = 880 ÷ 14.31818e6 ≈ 61.5 µs
- Horizontal frequency = DotClock ÷ HTotal ≈ 16.27 kHz
So each scanline is 880 clocks long, with 720 visible → about 81.8% of the line is image.
Vertical section
- 240 = VDisplay (active lines per frame, visible).
- 243 = VSyncStart (line where vertical sync pulse begins).
- 246 = VSyncEnd (line where vertical sync pulse ends).
- 270 = VTotal (total lines per frame, including blanking/sync).
- Frame time = VTotal ÷ HFreq ≈ 270 ÷ 16.27k ≈ 16.6 ms
- Vertical frequency ≈ 60.2 Hz
So 240 of 270 lines are visible → about 89% vertical duty cycle.
+HSync +VSync
- Sync polarity flags. Your Brother CRT expects positive polarity pulses for both H and V.
- If wrong, you’d typically see rolling, mis-centering, or no lock.
Big picture
- Resolution: 720 × 240 active (about 90 text characters wide × 24 lines of text).
- Refresh: ~60 Hz, ~16.27 kHz line rate.
- Dot clock: 14.31818 MHz → matches the kind of master crystal a Brother word processor board would have used.
Which for Fabgl using modeline, is written as:
When setting up the VGA object, I used the 2 colour method, specified the gpio pins I wished to use and set the R, G & B pins all to the same pin. This forced true monochrome with no shades.
So for example, in a sketch with #include <fabgl.h>
fabgl::VGA2Controller VGA;
fabgl::Canvas canvas(&VGA);
setup()
{
//set up the CRT
VGA.begin(GPIO_NUM_12, GPIO_NUM_12, GPIO_NUM_12, GPIO_NUM_32, GPIO_NUM_15);
VGA.setResolution("\"BROTHER\" 14.31818 720 736 776 880 240 243 246 270 +HSync +VSync");
//setup and display hello world
canvas.selectFont(&fabgl::Color::White);
canvas.clear();
canvas.setPenColor(fabgl::Color::White);
canvas.setBrushColor(gabgl::Color::Black);
canvas.drawText(1,1, "Hello World");
}
So you can take this as a basic template and start to use the fabgl methods to start drawing on screen, or modify existing examples by replacing the old dispaly setup with those new values.
For example, one for the first things I loaded was the Space Invaders example, and made these small changes.
WARNING: I highly recommend you use your oscilloscope before you plug into the CRT anytime you change the timing values. You should at least make sure the H sync and V sync coming out of the ESP32 are the right frequencies. If you try to drive the CRT with much more of a different frequency than the circuitry expects, you can damage it permanently!
Step 5: That's IT!
So once you get something to actually show up on screen, you have all the tools in the library (use the documentation) to create your own applications or modify others to work on your Brother. I'm not finished with the keyboard decoding yet, so it will have to be a separate guide. Have fun!

