Saturday, September 19, 2026

Connecting a CPU: A change of direction

         My original plan for this project was to pair it with a 6502 CPU system and build a simple 8 bit homebrew computer. But as I approached the point where I’d need an external system to run code on, I had several realizations.

        The first problem was that I didn’t have a 6502 computer system to connect it to. And while it wouldn’t be that hard to build one, it was a project that I wasn’t really sure I wanted to undertake.

        Because the second problem is that I have zero experience with 6502 assembly programming. My early programming experience was all on Z80 and 68000 machines, and even there I was using interpreted and compiled languages and not touching the assembly myself. I didn’t start doing low-level assembly programming until much later.

        And that leads to the third problem: programming 6502 machines isn’t nostalgic for me. A homebrew 6502 system isn’t my dream retro machine. I never really did any programming on them. The vast majority of my actual programming experience has been with Microchip PIC series microcontrollers, starting with the simple 8 bit ones back in the 90s, and leading up to the PIC32 devices I work with today. 

        And as it turned out, I had a PIC32MZ development kit board sitting around unused, left over from a previous project, and the development and debugging environment already set up and ready to use.
It is true that the resulting system isn’t going to be all that retro, with a modern (200mhz, 32 bit) CPU, and a modern FPGA. But it would be a lot easier for me to develop, and it would at least look and act like a retro boot-to-basic machine.

        I created code in the FPGA to make it act like a 64K memory, with internal division between control registers, tile and text maps, sprite data, graphical data, etc. In the Microchip code project I configured a chunk of the PIC32’s memory space to connect to the FPGA through the MCU’s external bus interface. Then I just needed to connect 16 address, 8 data, and various control signals between the two of them.
With some fairly simple code I was able to write to the FPGA, clear the memory space, and make a simple hello world program to draw text to the screen.

Connections between the MCU and the FPGA 

 

Wired up with a ribbon cable, and a simple 3D printed frame to hold everything stable 

        The next step was to connect a keyboard, using the USB Host capability of the PIC32 MCU, and create a simple text interface. This wasn’t terribly difficult to do, although I had a little difficulty getting key repeat timing just right. I also added a SD card interface, and wrote a rudimentary DOS for saving and loading files.



        At this point I had a simple “TV Typewriter” type interface. But to make it really useful, I would need to implement a scripting language – preferably Basic, since that matches the type of computer I was trying to imitate.

Designing the graphics engines: Text, Tile, and Sprite graphics.


         

        At this point, I had a simple FPGA program to output a HDMI video signal consisting of a single static image. This was a start, but to be useful it needed a lot more functionality.


        I would eventually need to code a CPU interface to allow the contents of the frame memory to be written externally, but first, I wanted to code the actual GPU function. My goal was not to have a simple bitmap display, as that would require the external CPU to do a lot of work to draw simple text and tile graphics. Instead, I wanted to build graphics engines to make the CPU’s job easier. The system I was imagining needed an easy-to-use text mode, as well as multiple tile and sprite layers for implementing simple games. I quickly came up with a design that would have four independent graphics engines: text, tile A, tile B, and sprite, running simultaneously to generate different layers of the final screen image.


        The 75K frame buffer took up far too much of the FPGA’s limited memory, so it would have to go. Instead, the individual engines would each have a dedicated line buffer, and would generate the image to the screen line-by-line as needed, racing the beam as it moved down the screen. I actually created two line buffers for each graphics engine, with one of them being written to while the other one was being read out to generate the video output. After each line the buffers would be swapped, so the most recently generated one would be output while a new line was being generated.


        The block RAMs on the T20F256C3 are each 512 x 10 bits, which fit my needs for this well enough. I was only using 240 locations out of each block, but the 10 bit width came in handy. Of those I was using 8 bits for the color value, while the remaining 2 bits were used to encode a layer priority value. When reading data from the four line buffers, the priority values from each would be compared, and the color value with the highest priority would be used as the color value sent to the palette memory. With this each sprite in the sprite engine could have a different layer priority, allowing them to appear in front of or behind the tile layers as desired. Likewise different parts of the tiles generated by each tile engine could have different layer priorities relative to the sprites and each other.

Simplified block diagram of the graphics pipeline.


        The text engine stores a 64x32 page of text in memory, although only 40x30 characters are visible on the screen at once. While it would have been nice to be able to implement 80 column text mode, I haven’t come up with a clean way to fit it into this existing architecture yet. Each character is stored as 4 bytes in memory: one byte for letter ID, one byte for foreground color, one byte for background color, and one ‘attribute’ byte which encodes various bits for cursors, underline, blinking, and per-character layer priority. This came out to 8K for the text map, plus 2k for the 256 character font, which might seem a lot for a simple text display, but I wanted it to have a lot of built-in functionality. I also much later added a feature to allow this space to be repurposed for other uses by disabling the text engine.

         A single byte in a general-purpose control register space allows the text display to be shifted up and down on a per-line basis, allowing smooth scrolling if the external CPU wants to implement that.


        The two tile engines are identical, other than pointing to different line buffers and reading from different memory banks in memory. Similar to the text engine, each 8x8 tile on the screen is stored as 4 bytes in memory. One byte selects the tile image ID, one selects the transparency color (pixels on the tile matching this color will have their layer priority set to zero, allowing other layers to show through), and then there are two bytes encoding various special features. The tile map encodes 64x32 tiles, requiring a total of 8K of memory, and another 8K of memory is set aside for the tile graphics.


        There’s a lot of fancy functionality built into the tile engines. Each tile’s image can be encoded in 256 color, or 16 color with a per-tile palette selection. Tiles can be individually flipped horizontally, vertically, rotated, or any combination of those. There is also an automatic animation function where a tile’s image can be cycled at a per-tile adjustable speed. Each tile can have an individually adjustable layer priority, so you can have effects where some tiles are in front of the other layers and some are behind them. There’s also a collision bitmask for detecting sprite-to-tile collisions, although that feature hasn’t been well tested at this point.


        There are also scrolling registers in the general control register space which allow each tile layer to be scrolled in X and Y on a per-pixel level. It’s also possible to generate parallax scrolling effects by having the external CPU change the X scroll register between scanlines.


        Finally, there’s the sprite engine. This handles up to 128 sprites on the screen at once, and is one of the more complex bits of coding in the project. Each sprite requires 8 bytes of RAM, requiring 1K of RAM for the 128 sprites. Initially I set aside 16K of RAM for the sprite graphics, which turned out to be a fairly severe limitation. I later added provisions to increase the sprite graphics memory up to 64K, by allowing the sprite engine to use other areas of memory when the tile or text engines were disabled.


        Sprites have 10 bits of X position and 9 bits of Y position. These are signed integers, which allows a sprite to be partially off the top or left side of the screen with a negative location. Sprites must be square, but can be 8, 16, 32, or 64 pixels wide. Like tiles, sprite images can be flipped horizontally, vertically, and/or rotated, and their images can be stored as 16 or 256 colors. There is also a feature to automatically animate sprites, rotating their image through several with adjustable timing, and a sprite-to-sprite and sprite-to-tile collision detection system.


        The code of the sprite engine is more complicated than the other engines. First there is a scan process that iterates through the data for the 128 sprites, reading the next sprite's data from the sprite data registers and passing it to the sprite math block.

       The sprite math block determines if this sprite is potentially present on the current horizontal line being drawn to the line buffer. If the sprite is to potentially be drawn, the math block generates a command to be sent to the blitter. This command includes source address in memory, destination address on the line, and information about how much and in what direction to increment the source data pointer between each pixel - required for sprites which might be flipped or rotated. The math block also takes into account the animation cycle, moving the data pointer between animation frames as needed. This information is all packed into a 64 bit command which is sent to a command FIFO.

        The command FIFO holds up to 16 blit commands. If the FIFO happens to be full - possible if multiple large sprites are handled at once - the scan state engine gets paused until there is a free spot in the FIFO. When there is a command ready in the FIFO, the blitter engine takes the command and copies the indicated pixels from the sprite bitmap memory to the line buffer.

        There is no hard-coded limit to the number of sprites per line. In theory, if you draw too many large sprites to the same line at once, the blitter will at some point run out of time and be unable to finish drawing all of them before the line buffers get swapped and sent to the screen. I’m not entirely sure where that point is yet, I need to do more testing.

        I figured that these four engines should be enough for a machine that would be more than comparable to any early 80’s 8 bit boot-to-basic or home game machine. The next step would be to connect an external CPU and actually write code to run it.

The Game Engine: A homebrew boot-to-basic retrocomputer built with modern hardware.

 

Current appearance of the GameEngine as of this year. 

        The GameEngine is a project I've been working on intermittently for the last five or so years. It's an excuse to learn FPGA programming, a fun exercise in making my own fast Basic interpreter, and a demonstration of how you can build a flexible GPU system with relatively low-end components. Functionally, it's a modern retrocomputer, a machine inspired by the 8-bit computers that I grew up with in the 80s, but built with modern components. The current version uses USB peripherals, stores files on a SD card, and outputs HDMI video, but acts like a text interface boot-to-BASIC computer similar to classic machines from Commodore, Texas Instruments, or Apple.


        This project’s inspiration came from multiple sources. It was partly inspired by the Commander X16 project, which got me thinking about how I would build the kind of classic computer I would have liked to have while growing up. It was also inspired by looking at many other homebrew 8-bit computers, and noticing that they were at best producing VGA video output. HDMI output was apparently too difficult to do in a homebrew system, at least while still using discrete logic. This started me wondering what the minimal hardware system that could generate HDMI video would be. I figured that a FPGA would be required, but that was fine with me as I was looking to get more FPGA programming experience anyway.  


        My initial idea was to develop a custom computer system, a board containing a 6502 CPU, RAM and ROM, and a FPGA on a dedicated daughterboard plugged into a standard DIP socket. The FPGA would generate video and sound output, and would also take over much of the glue logic functions, generating clock and reset, address decoding for the RAM and ROM, possibly keyboard handling and maybe even smart interrupt and DMA functions. But first I needed to demonstrate the basic video function with a devkit board.


        The really low-end FPGAs from Lattice and Microchip were too small to do what I wanted, while the powerful high-end ones from companies like AMD were expensive and at the time had very long lead times. I decided on the mid-range FPGAs from Efinix, as they were relatively inexpensive yet had enough LUTs and on-chip RAM to do what I needed. For this project I chose a development board based around the Efinix T20F256C3.


        The T20F256C3 does not have a built-in HDMI driver, but it does have multiple LVDS output channels.  LVDS signals don’t quite match the required voltage levels of the HDMI data channels, but a simple RC network was enough to get them close enough to work. I built up an adaptor board to plug into the devkit and output close-enough HDMI video signals.

 

 
 A simple LVDS to HDMI adapter circuit.
 
 

 The circuit built up on breadboard, plugged into the FPGA devboard.


        The  ideal thing to do would be to use an actual HDMI signal driver chip to get the proper voltage levels and drive strengths, but I didn't want to bother with having to set up an entire breakout board for that. The simple RC network seems to work well enough, even if the signal levels here only marginally meet the HDMI signal specifications.


        My first goal was to see if I could simply display a static color bar image.  HDMI digital video output consists of four differential channels: red, green, blue, and clock. The color channels are transmitted as ten bits per pixel data signals. The fourth channel is simply a clock signal which cycles once per pixel. Horizontal and vertical sync are added to the blue channel, and additionally audio data can be included during the sync period on the red and green channels.

 

 


        I was aiming for a 640x480 pixel image, the baseline screen image that all HDMI monitors should accept. With horizontal and vertical sync and blanking periods, each screen consists of 800x525 pixels, or 420,000 pixel clocks per frame. A 60hz update rate would require a 25.2mhz pixel clock. Unfortunately the FPGA I was using couldn’t easily generate this exact clock rate from the clock signal on the devkit, but it could easily make 25mhz, which would give me a frame rate of 59.524hz. This seems to be close enough for the monitor to recognize.


        The data on the red, green, and blue channels is TMDS encoded, which converts the data from 8 bits of raw color information to a 10 bit signal encoded to balance voltage levels and minimize transitions. The blue channel also has some additional encoding for indicating horizontal and vertical sync signals. For this part I simply grabbed some open source TMDS encoder code and pasted it into the project, rather than bothering to write my own from scratch.  Thanks to Scott Larson for creating and publishing that code for me to use.


        I wrote up a simple timing block to count through the horizontal and vertical pixels, and generate the blanking and sync signals as needed. A simple case statement based on the horizontal position was used to generate color signals to the encoders.

 

Color bars. I had the red and blue channels swapped here, but that was an easy fix.

 

        At this point, I had a valid video output from the FPGA, with surprisingly little code. Next step was to see if I could make it display a static bitmap image.


        The video output at this point was a 640x480 pixel, 24 bit color image. Storing that image at full resolution and color depth would require over 900KB of RAM. The Efinix T20F256C3 FPGA only has about 100KB of block memory, so I would have to make some sacrifices to  get a raw bitmap image to fit.
First thing I did was halve the resolution. Doubling up each pixel horizontally and vertically meant I only had to store 320x240 pixels in RAM. This was about the graphics resolution I was aiming for with the final design anyway.


        The second step was to switch to 8 bit indexed color. I created a palette lookup table, three 256x8 bit memory banks holding the red, green, and blue values of each indexed color. Instead of holding raw color values, each byte in the bitmap image would have the index of a color to use from the palette RAMs.  

 

256 color demonstration, using the standard ANSI color table.

 

        I created a quick Python script to take a raw image, find the closest color in the palette, and then output a raw memory file. I even added a feature to dither between two colors when the raw color in the image was roughly between two choices.


        With the reduced resolution and indexed color, the memory required for the image was reduced to only 75K, which would fit in the block ram of the FPGA. I created a single block RAM to hold the image, with its contents initialized from the memory file created previously, and replaced my simple color bar generator with a lookup function to fetch the required pixel from the block RAM. This worked, and I now had a simple FPGA code to display a static image over HDMI.

 


 256 color parrots, in 320x240 resolution.
 
        That's video output. The next step will be designing the interfaces that would let an external CPU do something useful with this.
 
        The latest FPGA code for this project can be found in my github repository at https://github.com/ellindsey/graphics_engine/.
 

Friday, November 12, 2021

Refurbishing an Apple IIe found thrown out on the curb

    Earlier this summer, on a cloudy afternoon with thunderstorms coming, I was out for a quick walk around the neighborhood. The area recently had suffered from some devastating rainstorms with severe flooding, and many homes had flood-damaged furniture and other items piled up on the curbs out front. I gave most of the piles a wide berth, but one such pile immediately caught my eye. 


    I was quite astonished to see, among the other obsolete electronics, a vintage Apple IIe just left out in the trash. Even if it was flood-damaged, this machine was well worth the time to refurbish. This was also a machine with a lot of nostalgic value for me, as I grew up using these in grade school, but not one I had ever actually owned myself.

    I did wonder briefly about the ethics of picking these up - perhaps the people who lived there were merely temporarily storing the parts on their curb, and taking them would be stealing? But they had been obviously dumped as trash along with flood-ruined furniture and bins of rubbish, so I figured they were clearly trash. Furthermore, there were thunderstorms coming to the area later that evening, so whoever left these out obviously didn't care what happened to them.

    I ran home to get the car to come and pick it up, slightly worried that someone else would grab it before it got back but more worried that the approaching thunderstorms would reach us and potentially cause even more flood damage. I ended up grabbing the Apple IIe, the floppy drive, and the printer underneath it that seemed to be associated with it. Unfortunately neither of the monitors near it were compatible with the video output of the Apple, both being VGA input monitors while the Apple produces a slightly non-standard NTSC signal.

Inside the Apple IIe



    The Apple II came at a time when home computers were just starting to shift from made for electronics hobbyists to being useful consumer devices. The Apple I had been entirely made for electronics hobbyists, with the expectation that each end user would be writing their own software and designing and building their own expansion hardware. They were sold as a completed PCB only, with finishing details like a case, keyboard or display being up to the end user to provide. It was as much a learning tool for the people at Apple as much as the end users. The Apple II would be a more complete machine, usable out of the box, with a built in BASIC programming environment that could be more easily used for writing your own programs. It was however still designed for easy modification and repair, with all of the chips on the board socketed, and was built entirely with components that were easily available at the time.

    The IIe was similar to the II in functionality and design, but many of the discrete logic chips were replaced with three custom chips designed by Apple: 
  • The PAL/HAL, which contained high-speed logic that generated the various clock signals used by the rest of the board.
  • The MMU, which performed some complex address remapping to allow the CPU to access the full available memory space (128K of RAM on most machines, plus ROM and memory-mapped registers) with only a 16 bit address bus.
  • The IOU, which managed the clocks and counters for the display, the audio output, and various other input and output functions.
    While the Apple IIe was still designed for easy repair and modification, with all chips still being socketed on the early models, these three chips were only available from Apple (and are hard to find today).

    The Apple IIe, with 80 column text mode and 128K of memory in most models, was actually useful for some business and publishing purposes in addition to being a useful learning tool. American schools and universities bought these in vast numbers, ostensibly for educational purposes although they were largely used for playing games.

    Apple would continue its shift from hobby machines you could open and repair towards building machines with no user-serviceable parts over time, which eventually resulted in the early Apple Macintosh computers with cases that required specialized tools to open and had no user serviceable parts inside. I grew up using those early Macs, and while I learned a lot about how to program from them the hardware of those machines might as well have been a sealed black box to me.


    This particular Apple IIe was one of the earlier ones made. From the color of the lettering on the keycaps I could tell it was from the first year they were manufactured - later IIe machines had dark lettering versus the cream lettering of the first-year models. It had the original version ROMs, and was not one of the later 'enhanced' models. This one also still had the pseudo-Velcro fasteners on the lid, allowing it to come off with just a good pull, which were replaced with more conventional fasteners after the first year. 
    
    One especially nice thing about this computer is that there is really nothing on the board itself to cause corrosion. No batteries to leak, and no electrolytic capacitors on the motherboard itself. There wasn't much even dirt or corrosion inside, the board was in such good shape to make me doubt that it even had been flood-damaged in the first place.


    It had a 64K / 80 column expansion board in the memory expansion slot, a special card slot dedicated to just this card. Though technically an expansion card, this was standard equipment in nearly all IIe machines. Early machines came with a simpler card that only provided the 80 column feature with no memory that the system could access, but those were replaced in nearly all machines with this improved versions.


    Also found in nearly all Apple IIe machines was this dual disk drive interface card. A curious thing to see is that these early cards had no back-panel connections as you would see on expansion cards in modern computers. To connect a drive, you had to feed a ribbon cable in through a hole in the back of the case and plug it directly into the board itself. This card could connect to two floppies, although I only found one with it. I also hadn't found any actual floppy disks, so I wasn't sure if I even could properly test this card.


    It also had this Grappler Printer Interface card, presumably to connect to the printer that had been dumped in the same pile. I also had no idea how to properly test this, since I didn't have any of the software that would be required to use it, and while I had also grabbed the printer it looked to be in really poor shape.

    After taking the machine completely apart, I cleaned all the connections and card edge fingers with Deoxit and rubbing alcohol. There was a fair amount of dust, but no larger debris, and not much corrosion to deal with. It looked almost ready to power up and test, but before I did I needed to attend to the power supply.

Fixing the power supply


    Unlike the rest of the machine, the power supply was most definitely not intended for the end user to open up and work on. There are dangerous voltages exposed inside these while they were operating, and really no parts that the end user would normally need to access.  Unfortunately, unlike the motherboard, these did contain capacitors that would fail over time and need replacing. Considering the age and possible water damage, I didn't dare even power this supply up without first opening and examining it.


    The copper traces on the backside of the power supply PCB are a work of art. Boards like this were laid out entirely by hand, with a hand-drawn mask being used to generate the pattern to etch the copper traces. There's not a straight line on this thing. You don't see this kind of almost artistic effect with modern PCBs that are laid out on a computer.

    The electrolytic capacitors in the supply looked undamaged, and there wasn't any significant corrosion, but I quickly spotted the one part that would need replacing.


    These RIFA filter capacitors go bad after a few decades. Moisture seeps in, causing the insulating materials to swell and break down The case cracks from the swelling, letting more moisture in, and the degraded insulation loses its insulating abilities. You can see from the crack across the housing that this one was pretty far gone. If I had plugged the power supply in while in this state, it would probably have shorted out and caught on fire.

    Fortunately, replacement filter capacitors are still available.


    One online order later and I had a new part to swap out for the damaged one. This should be good for another few decades.

Cleaning the case and keyboard


    The keyboard on this machine showed signs of heavy use. The outside was grimy, there were odd stains on several of the buttons and the surrounding case, and many of the buttons were sticky and didn't press easily, or were slow to return when pressed. Fortunately, most of this is easy to take apart and clean.


    The keys come off easily enough, allowing me to clean the keyboard mechanism beneath them. I managed to improve the action of the sticky keys a little, but I could see that completely cleaning them would require desoldering all the keys from the board underneath and actually disassembling the individual mechanisms. I wasn't confident that I could do this without damaging the keyboard worse in the process, so for now I'm just settling for exterior cleaning. I may return to these at a later point.


    The power light on the keyboard is actually a tiny incandescent light bulb, which was still intact and working. Some people replace these with a green LED, but since it was still working I decided to leave the original bulb in there for now.


    The keys themselves I soaked in soapy water for a while and then scrubbed and washed individually. This didn't help with the sticky key actions, but it at least made them look a bit better.


    The case also went in the sink for scrubbing and cleaning. I'm not going to go as far as retrobriting it yet, so there's still some yellowing, but at least I got the stains and grime off of it.

The floppy disk drive



    Though slightly battered and dirty, the floppy disk drive looked mechanically intact. I gave it a similar treatment to the computer, opening it up, cleaning and inspecting all the parts. There was no significant corrosion, everything moved freely, and all of the capacitors looked good. The weird spiral cam that moves the head had some hairline cracks at the end stop, but they didn't look like they would interfere with normal operation.

Testing and troubleshooting


    With everything cleaned and the bad power supply capacitor replaced, it was time to put it back together and actually test the machine. I hadn't been lucky enough to find an original Apple monitor with this machine, but we still had my wife's old Commodore monitor which I was able to convince to work with the slightly non-standard NTSC output of the IIe.


    At first, it looked great. The machine beeped, and the disk drive whirred and thumped. When I exited out of the normal looking-for-a-disk boot process, it went to a text prompt, and I could type in simple BASIC programs. The sticky keys on the keyboard made typing a slight nuisance, but I managed anyway.


    A glorious 16 colors. This may not look like much now, but at the time it was amazing, considering that many of the computers of the day were monochrome only, or used the really quite ugly and limited CGA color palette.

  A tip from a friend led me to the software archive at Ascii Express and its incredible collection of Apple II software. Their files are all saved as audio clips, intended to be played out of a computer's line out port into the cassette input port on the Apple II. With a little searching I found an audio patch cable, connected the IIe to my laptop, and was able to load and play some of those nostalgic games from grade school.


    Nearly 40 years later, and I still suck at this game.

    Unfortunately, after a few hours of testing, the IIe developed video glitches.


    White lines down the screen while in text mode, extending from the top of the screen downward before breaking up halfway down. These would creep up and down the screen as the computer warmed up, sometimes vanishing entirely. Switching to 80 column mode would not fix the problem, but the white lines would become twice as dense. In color mode, the white lines would go away, but instead there would be lines of shifted and changed colors, in vertical bars creeping up from the bottom of the screen.


    I wrote a quick test program to make horizontal bars of colors repeating across the screen. This should have shown solid horizontal bands of each color, but graphical glitches were present, creeping up from the bottom of the screen. The pattern was strange, with some colors being shifted to other colors, or going black entirely. This was also visible when playing games, with bars of shifted colors creeping up the screen. The effect was happening on every other pixel, although the nature of the color shift changed in a regular repeating pattern across the screen.

    My first thought was bad RAM, mostly because that's the most common failure on these old machines. The 64Kx1 DRAM chips used on these old Apple computers are known for having a high failure rate after after a few decades. But the Apple's self-test routine passed with no errors, indicating that the RAM and the major internal data paths were all intact.

    My second thought was to look at the video output circuit, and in particular the video ROM and its associated shift register.


    Each character used in text mode is a 7x8 pixel bitmap, which are stored in the video rom UF4. To display a character, 6 bits of data indicating which character to show are loaded from RAM, the lower 6 data bits going to address bits A3 to A8 on the video rom to select the character. Address bits A0-A2 are used to select which vertical line of the character is being displayed, and are generated from a counter in the IOU chip. The ROM provides 7 bits of pixel data on its outputs O0-O6 (O7 being unused in text mode) which go to the shift register at UF5. That shift register then hands those bits one at a time to the analog circuitry that drives the video output.

    In color mode, the system is run at a higher speed, and UF4 generates bit patterns for each pixel which the attached monitor interprets as color information. UF4 actually generates data for two pixels at a time, with the low bits O0-O3 being the first pixel and the upper bits O4-O7 being the second pixel. It could generate sixteen different bit patterns for each pixel, which accounted for the sixteen colors which this machine could generate.


    I could see from the screen that the video problem were always occurring on the same positions on each character. For each character, the last two bits - corresponding to O5 and O6 on the ROM - appears to be stuck on. In graphics mode, every other pixel had incorrect colors, which would also match a problem with those two pins, since outputs zero through three generate one pixel and four through seven the other in each pair.

    
    The problem could have been in either the video ROM, the LS166 shift register, or possibly even the pull-up resistor network, or maybe even a bad connection in the sockets. I removed both chips and cleaned their pins and those in the sockets, but this made no difference to the graphical glitches. The resistor network also checked out with proper resistances on all pins, so I was pretty sure this was a failure either of the outputs on the ROM, or the inputs on the shift register.

    Ideally, I would have stuck an oscilloscope probe on these two pins and looked at the signal. I don't have an oscilloscope at the moment in my home lab, so I had to make do without. Instead I checked the voltage on the output pins of the video ROM individually when displaying different modes and contents on the screen. I observed that when the screen was mostly black, the output pins O0-O4 on the ROM were at nearly 5V, as expected. (There's an inverter in the video output circuit, so a high on the output pin corresponds to black.). The voltages on the O5 and O6 pins on the other hand were drifting low, and that drifting corresponded with how far the white bars were extending down the screen. This suggested that the outputs on the ROM chip were failing. Although I couldn't completely rule out some kind of weird short on the input pins on the shift register loading down the ROM outputs, I was pretty sure it was a bad ROM chip causing my problems.

    Unfortunately, you can't easily buy just a replacement video ROM. I ended up buying the full Apple IIe Enhancement kit from Reactive Micro, consisting of replacements for all three ROMs and a new CPU. It even includes an "Enhanced" sticker for the keyboard.


    Swapping out these four chips was an easy job. Everything being socketed in this machine makes chip replacements easy. Other than the bad capacitor in the power supply, I haven't had to touch my soldering iron.


    The replacement ROMs and CPU completely fixed the problem, and now my IIe has been upgraded to the Enhanced version, which offers a handful of new kernel ROM features that I probably won't use.

Back to the floppy drive


    The software archive at Ascii Express includes not just games, but utility programs and disk management utilities. With the computer itself working well, I turned back to the idea of testing the disk drive. But first, I needed an actual disk. I have a whole bin of 3.5" floppies, but no 5.25" ones, and didn't know anyone who had any still on hand.

       A computer swap meet or retro computer show would have been a good place to ask, and I may do that next time I go to one. For now, I headed over to Greenbrook Electronics to check through their surplus area to see if they might have any. It was a long shot, and I spent a while digging through their old computer parts bin, before finally finding what had to have been the last floppy disk in the store.


    I wasn't highly confident in how well this would work, considering that this disk was literally buried under a pile of junk, but I really had no other options, and they only charged me a dollar for it.

    Using some of the software from Ascii Express, I was able to format most of the disk, but it would always fail with a disk error near the end of the process.


    I had some luck running the utility programs, and was able to read and write files from most of the disk, but again would run into failures with the later parts of the disk.


    Bad disk, or something wrong with the drive? I don't know. Given the suspicious state of the disk and that the drive seems to be intact and working otherwise, I suspect a bad disk, but I can't say for sure. I need to get my hands on some known good disks to test for sure. Honestly I'm not sure how much of a priority fixing the drive is, since most serious collectors will just stick a SDcard to Floppy adaptor on their machine anyway rather than try to find working floppies.

How about the printer?



    The other piece of equipment that I grabbed off the trash pile was this ancient Epsom FX-80 printer. I grabbed it mostly because it obviously went with the Apple IIe, and figured that I could possibly sell or at least donate it to a collector eventually. I didn't have much hope for being able to really test it, lacking the software needed to drive it, or the perforated paper or ink ribbons it needed. The most I could do was clean it up and make sure that everything looked right.


    Unlike the Apple IIe, the inside of the printer is filthy. Full of mouse droppings, and with severe corrosion on many of the circuit boards. Someday when I'm feeling very ambitious I'll completely tear this down to bare parts and deeply clean it, but for now it's going into storage.

Bonus: Making a joystick

    While playing through the archive of games available, I soon realized that most of the games for the IIe either required a joystick to play, or worked much better with a joystick than with a keyboard. The keyboard controller on the IIe only recognizes one key being held down at a time (other than special keys like shift and control) which isn't ideal for platformer games where you might need to jump and run sideways at the same time, for example.


    Rather than buy a vintage joystick on an auction site, I figured I should be able to make my own. I had a few spare joystick mechanisms lying around from other projects, and some nice pushbuttons. I'd just fire up Solidworks, design a case to hold them, print it out and wire it up. Easy, right?


    Unfortunately it's not as easy as just wiring a joystick to the inputs on the IIe's game port. While a modern game system would look for a variable voltage input and resolve it with an ADC, the Apple IIe uses a timed charge-discharge circuit to detect the joystick position. It actually uses a quad 555 chip to generate a square wave with the pulse width determined by a RC circuit involving the joystick potentiometers. This was specifically designed to work with a joystick that uses 150K potentiometers, while the ones I had on hand were 10K potentiometers.

    Blondihacks came to the rescue here, with a hack that let me use my existing 10K potentiometer joystick with the Apple. By adding some additional capacitors between the joystick analog pin and ground, it is possible to shift the RC constant enough for the 10K resistance to work.


    There was just enough room in the case near the pushbuttons to fit in several caps in parallel to give the 0.31uf capacitance needed to make the circuit work. I also decided to use illuminated pushbuttons powered by the 5V from the joystick port, mostly because they were what I had on hand, but also to look fancy.


    A purist would probably sneer at this, as it looks and feels nothing like the original Apple joysticks, but it works well enough for gaming, and is comfortable in my adult-sized hands.

What now?

    At this point I think I've done about all with this machine that I'm going to. The printer is probably not worth repairing, and the disk drive should be replaced with a SD card reader, but I'm probably just going to sell this machine to a collector now. My wife and I are actively trying to clean out our condo and get rid of anything that we don't use frequently, and I can't justify keeping a machine like this around when there are certainly dedicated collectors who will pay to have it. Though really, I'm just happy that I spotted it at all and that it didn't end up being destroyed or sent to a landfill.