Build of MCUHacker01's ESP8266 PCXT Emulator

Notes on problems faced (some solved).

Public Chat
Similar projects worth following
My experiences pounding through a project.

ESP8266 PCXT Emulator Build Notes (In Progress)

I saw this project here on Hackaday ( ) and I just had to try it, to complement my 8008 and 8080 ESP8266 emulators. For you "kids", the original PC or PCXT with any kind of RAM or disks was very expensive, way beyond what a young person would buy straight out of college such as myself. The only way I could afford one was to solder up a bare board with parts, install it into a wooden box, build a (linear) power supply for it (I didn't have a prayer of building a switcher from scratch 35 years ago), get a (quite expensive) CGA card for it, and hook it up to a surplus black and white "monitor" that I had (which was basically de-contented, tuner-less 9" Admiral TV guts inside from the late 1960's). So, this machine emulates my first PC fairly closely.

 The emulator works, and it's amazing. The video is pretty darned good on my 9" Sony studio monitor.  The circuit on MCUhacker's website is missing a value for the output cap; I used 100uF and the video was fine. The video code itself will be very useful for me in other projects, although I can't believe that it would be compatible with highly interrupt driven WiFi (but, who knows). The emulator version posted on MCUhacker's site is incomplete and has a few oddities and bugs. I thought that I'd try to "fix" (i.e., "hack") it with my limited skills.

I had a bit of compiling trouble  due to some formatting issues in the code, but I straightened those out. I could not get the boot to MS-DOS working, but I'm saving that for last.

I knew that the keyboard was missing, so I thought that I'd put together some PS/2 code, and then combine it with a PCXT converter (both of which exist on GitHub). This was trickier than expected. The PCXT code was missing some key translations, so to speak, so I added them; a bigger problem was the levels between the +5 keyboard and the 3.3V of the ESP8266. Nonetheless, with 200 ohms between them and 4.7K pull downs at the ESP8266, I believe that I got this to (mostly) work, by making "fake open collector" outputs at the ESP8266. The keyboard pulls up to +5 through probably 10K resistors; when I want a "1" on the line, I turn the ESP8266 into an input and those resistors pull up to +5; when I want a 0, I turn it into an output which "shorts" the resistors to low. The keyboard to ESP communication works OK, but I cannot get the communication working yet from the ESP to the keyboard. Nonetheless , it worked, although the code is "big" and pushed the already strained size of the emulator up to using 88% of the RAM (although the tables are in ROM). I will work on shrinking this later.

The keyboard code was integrated into the emulator code via new "ports" for 0x60 and 0x61 (the 8155). I removed the fake int 16 handler. The "boot self test" 0xAA keycode creating procedure was also written.
After doing this, I can report that the emulator's speed is rather good computationally and good in writing video through int 10h (through direct RAM access, it's extremely fast and flicker free).

The second problem I tackled (not really a "problem") were the funny squiggles on the BIOS screen next to the "equipment list" (CPU, video) upon boot-up. I noticed this also when running ROM BASIC. It occurred to me that this involved line drawing characters, which were missing in the emulator's table. I actually found a source for these that I believe to be accurate, added this to the preexisting character lookup (only up to 0x7F) and now I could see the proper line drawing characters and BASIC didn't have them anymore either.  I'm unsure if this is a BIOS shortcoming or an emulator shortcoming (there is an interrupt that points to the location of this table in RAM, but in the BIOS, AFAIK, it points to zero, nonexistent). So, I wonder what this BIOS looks like when installed in a real machine with a CGA board - but who would do that even in the late...

Read more »

  • ESP8266 SPI PS-RAM?

    Steve L06/10/2019 at 04:59 0 comments

    I wound up using the hardware that I built for this for my 8008 emulator, and I really didn't give this project any more thought.  It seemed that the disk would fail randomly after loading a random number of sectors from MS-DOS.

    In the meantime, I bought an ESP32-CAM with a bad camera (actually, I discovered that one of the camera voltages was missing). So, I ordered a few more ESP32-CAM's and chalked it up to experience. But, the CAM board has a nifty SPI pseudo-static RAM component  (this version of the ESP32 has a 3.3 volt 8 meg PS-RAM). I wondered if it would be possible to connect it to the ESP8266 and use that for the 1 meg of storage needed for this project instead of the flash cache system, which is quite amazing, but still slow and brutal on the flash.  I built another version of the hardware, removed the PS-RAM from the ESP-32 and connected it up to the SPI on the ESP8266 board. After some datasheet and ESP8266 SPI mystery solving, I got this working.

    I'm testing the RAM now. The next steps, which might not happen for a while, would be to modify the original author's cache system to use PS-RAM and not the flash area of the ESP8266. it would be best to use it in "burst" mode, but, one step at a time!

  • Continued - MS-DOS "Boots"

    Steve L09/02/2018 at 03:33 0 comments

    So, I continued pounding on this problem, walking away from the imperfect but usable keyboard implementation and going on to the disk. It turned out that the flash wasn't really reading anything. The reason for this was my own ignorance. It is critical that you select an ESP-12E in the Arduino environment when working with a 4MB part (not the general ESP8266); the memory map is quite different. I've done projects with SPIFFS where apparently this problem was taken care of for me in the scripts that drive code building from the ESP8266 Arduino IDE.

    Another problem turned up involving me slapping myself on the back over putting the character generator ROM (with graphics) in flash. You cannot do this if you expect to read or write from the onboard user flash area at the same time. Now that the disk flash read actually worked, the screen flashed wildly with each flash read access.

    The ESP8266 actually reads instructions (and your stored constant values, strings, and so on) as needed into a ram cache. You can't do any of this in an interrupt that is not already in the ram cache. The nointerrupts () and interrupts() functions don't affect the i2s in the Arduino implementation of the ESP8266 (and even if it did, it would make the screen jumpy and unusable).  There are decorations for functions and variables that guide where the linker puts the components of the program.  I am barely familiar with these. So, I lost the graphics font for now, and so that the screen doesn't get messy, I put a check into the write into video that sets any >0x7F character to a space. The reason that I wanted to do the  above was the RAM situation. As the author released it, the RAM was 75% used. My cobbled together and mysteriously bloated keyboard code, which reads the PS/2 keyboard and converts it into XT code, added about 13-14% to that. This is pushing one's luck on stack/heap crashes, which apparently I've run into. I can get MS-DOS to boot, but it crashes before it hits the A:> prompt.

    Areas where I need to look for RAM:

    1. The PS/2 code (the "low hanging fruit" parts of this like the lookup tables may already be done)
    2 General code cleanup.
    3. Do I really need 4K for character video. Every other byte is for color/attributes(?). I have no need for it. But getting that 2k might require some changes to very tricky video code.

    I need more RAM for another reason; the original author didn't really finish the "disk write' part of the code. The tricky part here is that we are working with 512 byte sectors in DOS and the flash writes on the ESP8266 are in 4K blocks. So, if you want to write a 512 byte sector, you need to:

    1. Grab the appropriate 4K sector that contains the 512 byte PC disk sector in question from flash
    and put it in a buffer;
    2. Put the new 512 bytes into the appropriate 512K block of the 4K buffer
    3. Erase the flash sector
    4. Write to the appropriate 4K flash sector with the contents of the 4K modified buffer

    So, no matter what, this is taking 4K of RAM minus the 512 sector buffer that the code originally had.

    Even if the above worked, this will put a lot of wear and tear on the flash. A lot of writes are likely to be sequential, so I was thinking about a 'flash write cache" and a "disk activity" LED showing me when it is safe to remove the disk.  Basically, any writes to the 4096-byte area would be cached until either a few seconds went by or a write was needed outside of that area. That also will take code, and possibly, a little RAM.

    So, this is where it stands. I THINK that this can be done, but just barely, and really just barely by me!

View all 2 project logs

Enjoy this project?



RW wrote 10/05/2019 at 23:08 point

Hi again Steve, just now catching up on your June update, good stuff. Looking at this again, since I got hold of a couple of NodeMCU boards recently, and also a 80c88 fell in my lap, so I am pondering whether to find a way to splice the Fake86 peripheral etc code in a 8266 with an external real '88. I wonder if those PSRAMs are common in digital cameras, got a few old ones booting around I should look at.

  Are you sure? yes | no

Steve L wrote 11/04/2020 at 04:05 point

I got my PSRAM from a broken ESP32-CAM (the CAM part was broken), which I removed and installed on a breadboard adapter.

Other than as an interesting curiosity, I am not pursuing this project further; it will never be practical due to the lack of higher speed RAM IMO. However, the 80x24 video component of the original project has been INCREDIBLY useful, and I've used that code on other projects (my 8008 combined emulator/NTSC 80x24 terminal/PS2 keyboard project.

This might be worth looking at ported to an ESP32., maybe with multi-level caching.

  Are you sure? yes | no

Starhawk wrote 03/23/2019 at 00:28 point

@Steve L -- did this ever get fully worked out...? What is the current status?

  Are you sure? yes | no

Steve L wrote 03/31/2019 at 23:00 point

I haven't really touched this in quite a while; I'm still not certain if it's actually technically possible to do in any practical sense (like, get it up to 4.77Mhz seeming performance). I wonder what it would do on an ESP32.

  Are you sure? yes | no

RW wrote 09/05/2018 at 23:37 point

Since I can probably scare up 30 pin SIMMs, my thoughts immediately go to the arduino/SIMM project on here, to give it a decent chunk of memory. But I think a full 1MB which would give a whole 640 plus ROM shadows etc would take 10 pins, 256KB needs 9, so pin use is very tight. As far as I can remember for DOS, just to load and have a super basic DOS environment it needs about 6KB no TSRs/drivers.

  Are you sure? yes | no

Steve L wrote 09/02/2018 at 03:53 point

I have wondered if the original author already has these problems solved :)

  Are you sure? yes | no

RW wrote 08/26/2018 at 22:49 point

Nice work. I was a little disappointed in the original,  since it was starting to look like an abandoned proof of concept that didn't actually do anything. I would like to throw one together some time, but I have enough stuff to do that needs brainwork, and am not too familiar with 8266 yet, so I was in wait and see mode.  Either wait and see if it gets more complete/functional so I can throw one together in a day as a diversion, or wait and see if I run out of other stuff to do and get inspired to brain out all the deficiencies. 

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates