Back in February, I posted about my "Apple IIe" re-creation project in this thread (https://www.applefritter.com/comment/114042#comment-114042). At that point, my intermediate goal was simply to power-on to the AppleSoft prompt.
Since then, the project has progressed much and I thought it deserved an update. Some time after the above post, I achieved this intermediate goal and during this past summer, implemented most of what is the Apple IIe. This re-creation is now a working physical Apple IIe and can boot from disk images. It no longer looks like a promising project, but feels like a real Apple IIe.
The re-creation uses a real 6502-family processor, it uses USB Keyboard, gamepad, and mouse for the controls. It also uses a sd-card to read disk images and ROM images. The design is centered around a ESP32-S3 and a Lattice ECP5. The ESP32 is used for the sd-card I/O, USB events handling, and an "Admin Console" that will be used to configure the device. The ECP5 contains most of the design: MMU, IOU, HAL, RAM, AUX RAM, DISK II INTERFACE and DISK, CRT Emulator, etc. The re-creation outputs real HDMI 1.4 signals. I didn't want to implement a full HDMI Transmitter by hand so, instead I use a SII9022A with the ECP5 generating the 24-bit pixel data / audio islands. Also, the re-creation have a SDRAM chip to store the currently loaded disk images and the Admin Console video memory, and I had to add a USB hub to the design (a TUSB2046BIRHBT; the ESP32-S3 only has one USB Host port).
I like how the AppleColor IIe monitor emulation turned out. The original AppleColor IIe monitor looks better, of course. But still, this CRT emulation really manage to scratch that nostalgia itch. As described in the previous post, each Apple IIe pixel is pre-processed and rendered as a 3x6 block, then each line is post-processed. The resulting image is a 1680x1152 rendering, with black borders to make the image 1920x1200 at 60Hz.
Currently implemented is the 'core' of the Apple IIe with support for the 6502/65C02 or W65C02S (through a jumper), the Extended 80-Column card, USB Keyboard and Joystick support, the DISK II INTERFACE and DISK. The disk support is still pretty basic however: It only support 6656-bytes/track nibble images, it's currently read-only, and has only one drive for now.
The DISK II INTERFACE implementation took a lot of time. It's deceptively simple if you look only at the schematics; essentially a computer-facing 256 bytes ROM and a state machine powered by another 256 bytes ROM. But it has hidded traps; it turned out that recreating the Disk II interface was not just about reproducing the logic. The timing between the LS174, the P6-ROM, and the LS323 matters a lot too. Figuring all of this was really exasperating. Plus, I used the BMOW's FloppyEmu to do my development and I kept having strange read signals that weren't present when the FloppyEmu was hooked to a real Apple IIe. It took me so long to figure out what was happening. I eventually figured that when I changed the PHASE signals, if these signals were 3.3V, the FloppyEmu would corrupt the READ signal (I think it sent delay signals of some sorts). So, for the signals in the direction FPGA -> FloppyEmu, level-shifting to 5V is necessary. This is what was causing all this nightmare and the moment I tried voltage level shifting these outputs to 5V everything worked perfectly. I must have wasted close to two weeks scratching my head in frustration.
The SDRAM controller implementation have also been a bag of surprises. To be clear, I don't mean DDR SDRAM -- I'm not crazy enough to implement that! I use SDR SDRAM. I expected the command sequencing to be the hard part. But once you understand how they work, it's not that difficult. Simply put, the controller is 3 state machines: initialization, normal transactions (reads and writes), and refresh. You need to issue each SDRAM command on the correct clock edge while respecting the required delays between commands. For example, if tRCD is 3 clock cycles, there must be at least three clock periods between an ACTIVATE command and the following READ or WRITE command. So if ACTIVATE is issued on clock edge N, the controller issues NOPs on N+1 and N+2, and issue READ on N+3. No, the real challenge is achieving the timing requirements. I use a 150MHz clock and that means a clock cycle is 6.667 ns. The ECP5 is capable of achieving this and has hardware primitives to help, but still, that's where the real pain is.
There is still a lot of work to do. The biggest one is the Admin Console. The UI has been developed using LVGL on PC but still need to be integrated with the main ESP32 codebase. The UI is inspired by minimalistic/functional UIs like what could be seen in the Alien universe:
Monochrome and minimalistic, with a strong "The user is expected to know what he's doing" flavor. The spirit of the 80s.
Not yet implemented is the audio support, cassette support, mouse, and printer support. I'd like to throw in the ability to save/restore the Apple IIe state and a cheat console. But for now, my focus is on implementing variable-length disk image tracks and the second drive support. WOZ/Flux tracks will come later, but should be relatively easy as the nibble tracks are converted to flux internally.
This project has been a tremendous amount of work and my original idea was to sell these. But as time goes by, and as the price of components goes up, the less selling stuff seems appealing. And the more I think about it, the more I think I should just release it as open source once it's finished.
frozen signal
Here are other examples:
(Be sure to view them at 100% zoom to get accurate 1:1 pixel size, these image should be viewed as non-zoomed 1680x1152)
frozen signal


