Now obviously, the software is a fairly big element of this build: the entire Macintosh needs to be emulated. The Macintosh, however, is not that complicated a machine. It essentially consists of the 68000 microcontroller, a Zilog Z8530 serial communications controller that controls the serial port, a 6522 VIA for some internal input and output and for interfacing with the keyboard and some random PALs containing the logic for the display and sound. There also is an Integrated Woz Machine-chip to interface with the floppy drive. This is a fairly complicated chip; however I was not planning to emulate a floppy so for emulation it would be enough to emulate an IWM that always returns that there's no floppy in the drive. Instead, my plan was to fully emulate the NCR 5380 SCSI chip, connected to an emulated SCSI hard disk that would read from the onboard flash of the ESP32-Wrover module.

Furthermore, there are very few programs that attempt to access this hardware directly: programmers for the Mac were told from the start to use the OS-level hardware abstraction layers in order to stay compatible with later versions of the Mac hardware. In general, this means that when I succeeded emulating the hardware to a standard where the OS boots and stays happy, most programs would also run without complaints.

Because of this I decided I might as well program the emulator from scratch. Well, not entirely from scratch; the 68000 is a fairly complex beast and I didn't feel like reinventing that particular wheel. Instead, I looked around on the Internet, and MAME had a nice and quick C-based 68K emulator called Musashi that fit the bill nicely. It needed some slight mangling to put the lookup tables for the opcodes into flash instead of RAM, but otherwise it didn't need much to port to the ESP32.

However, I wasn't planning on developing the entire thing on the ESP32: while the chip has OpenOCD support allowing for a fair amount of debugging, the upload/test/fix/upload/... cycle would get pretty tedious. Instead, I decided to develop the thing on my Linux-machine first, keeping in mind the limits the ESP32 would eventually give me. So I went to work, using the datasheets for the various chips, the Linux-68K notes for the machine, as well as bits and pieces of the Inside Macintosh series that were floating around on the Internet. When I couldn't find out from these what to do, I still had the option to sneak a peek under the hood of other open-source emulators.

Armed with all that, gcc as the C-compiler and libsdl as the library to get graphics going, I set to work. Long story short, some time later I ended up having a basic but mostly functional MacPlus emulator: mouse, video, SCSI hard disk and sound all worked:

Because my hardware wasn't done yet, I decided to port my emulator to an ESP-Wrover-Kit devboard. I had access to a few of these boards anyway, and apart from the Wrover module I was going to use anyway, it also had a nice 320x240 display I could use to see if video works.

After some tweaking, the Mac emulator actually ran fairly well on this board; it usually comes pretty close to the 7.8MHz the Mac Plus normally runs at. (Actually, 7.8MHz would be slightly faster than a Mac Plus; because the frame buffer and sound system in the real thing eat up some of the memory cycles, the actual effective frequency could be as much as 35% lower.)

Obviously, getting the emulator working on a devboard is a nice step along the way, but in the end, the thing needs to run on the screen that I bought, not the devboard screen. And hold on a second, the devkit screen is 320x240 and cuts off a fair chunk of the Mac screen. The display I intend to use is 320x320 and as such only larger vertically: how am I going to get the 512x342 Mac screen displayed on it?

There's one way to put 512x342 pixels onto a 320x320 screen, and that is scaling. Effectively, you take an image, then squish it to make it smaller, then you display it. However, scaling can be done in multiple ways and especially with a black-and-white image generated by an OS that assumes every pixel it set results in a clearly distinguishable point of light on the screen, there are multiple ways to do it badly. Effectively, I would like to lose as little resolution as possible. This means I needed to increase the resolution of my OLED.

But how do you do that? I can hardly open up the OLED screen and squish some more pixels in there. However, I don't need to; the OLED display already has three times as many pixels as advertised. The reason for this is that the OLED screen is a color one: for each virtual 'pixel', it has a red, a green and a blue subpixel. Additionally, in this specific screen, the subpixels are laid out in triangles. To illustrate this, here's a close-up of the screen, with three pixels lit:

As you can see, the pixels are triangle-shaped sets of three subpixels; depending on the column they are on, the triangles either point up or down. This effectively means that our subpixel screen resolution is a nice 480 x 640 pixels instead. While still not entirely adequate for displaying 512x342 pixels, the difference is so small that with a small bit of well-chosen scaling the display looks as readable as an 1.63" display showing a GUI meant for a 9" screen will ever be:

« Prev 5 Next »

© 2006-2021 Sprite_tm - Contact