Implement i8080 emulation logic in Almquist shell, into the existing emulator driver of i8080bash which has the following commit log in a local Git repository

commit 15f13b53e8f5b0f55de2fb697a0ba607777c5be3
Author: WHR <msl0000023508@gmail.com>
Date:   Tue Nov 23 14:13:14 2021 +0800

    Workaround for BASH 4.3 on some platforms

commit 4704013b4bc6928890fbe4e7d31db3d50c81f65c
Author: WHR <msl0000023508@gmail.com>
Date:   Tue Nov 23 13:39:25 2021 +0800

    Ignore SIGINT when accessing memory or disks

commit 051c21bc2696850060335722b63452a34fe7fb42
Author: WHR <msl0000023508@gmail.com>
Date:   Fri Jan 29 21:15:31 2021 +0800

    Add SIGINT handler; add support of passing ^C into machine; add support of machine state saving and restoring

commit 8a9b2464d1fb30fea9c302462412430d19c490d2
Author: WHR <msl0000023508@gmail.com>
Date:   Fri Jan 29 12:31:32 2021 +0800

    Fix incomplete disk write in i8080.bash

commit 3f7669cc3ae78c67eed4e030e797cb0d273aa8d0
Author: WHR <msl0000023508@gmail.com>
Date:   Thu Jan 28 18:23:29 2021 +0800

    Discard dd(1) messages

commit 041f02d7e4ab9daf4d34aa0acd53b56eab824f03
Author: WHR <msl0000023508@gmail.com>
Date:   Thu Jan 28 16:05:47 2021 +0800

    Fix 'INR M' and 'DCR M' instructions taking address from PC instead of H and L registers

commit 79c58399f611b8927242957e3b83066e2b5f1732
Author: WHR <msl0000023508@gmail.com>
Date:   Thu Jan 28 12:32:58 2021 +0800

    Fix register A overflow failure in some instructions

commit 07d94164f59fecd4a503ca775657e3623b64d037
Author: WHR <msl0000023508@gmail.com>
Date:   Thu Jan 28 12:19:48 2021 +0800

    Remove disk I/O debugging messages

commit 9210361ae3ce38de37af3e1f4960d884e6c9615a
Author: WHR <msl0000023508@gmail.com>
Date:   Wed Jan 27 14:23:20 2021 +0800

    Set register A after disk I/O so CP/M could work

commit eba5627a6287516ec4077df2802842ba95c9572e
Author: WHR <msl0000023508@gmail.com>
Date:   Wed Jan 27 11:46:38 2021 +0800

    Refactor jump instructions implementation in i8080-rw.bash

commit 5b1db875d695c4516614d4862a0f1300f10947a4
Author: WHR <msl0000023508@gmail.com>
Date:   Wed Jan 27 10:06:36 2021 +0800

    Fix opcode 54 in i8080-rw.bash

commit 2c563ec932d8c07737a0f7c58a2a1eed4151f6d9
Author: WHR <msl0000023508@gmail.com>
Date:   Tue Jan 26 23:27:46 2021 +0800

    Fix reversed parity flag

commit 534b10cd1136289de010bbd3e94d96e813c6b77f
Author: WHR <msl0000023508@gmail.com>
Date:   Mon Jan 25 22:19:01 2021 +0800

    Fix syntax error

commit 9e18ac0c7fbd76baa1ccc5cd1cd175de5f27c1bb
Author: WHR <msl0000023508@gmail.com>
Date:   Mon Jan 25 22:16:09 2021 +0800

    Fix 'DAD SP' instruction implementation

commit 455dfb6096b40be0943ea54ce72359120b2a1898
Author: WHR <msl0000023508@gmail.com>
Date:   Mon Jan 25 22:15:40 2021 +0800

    Remove old versions

commit 1748c4a58a5a7f0170e2dbd79cbc5a68f5b49293
Author: WHR <msl0000023508@gmail.com>
Date:   Sat Jan 23 12:01:03 2021 +0800

    Start working with git(1)
6 files changed
tree: 474126d7b080d8a5e4718264effb7fe017d954a0
  1. COPYING
  2. README.md
  3. c_basic.bin
  4. c_bios.bin
  5. i8080-rw.ash
  6. i8080.ash
README.md

i8080 emulator for Almquist shell

A complete Intel 8080 processor emulator with emulated UART console and disk I/O, implemented in pure Almquist shell (ash) script. This particular emulated machine is compatible with the 8080 emulator written by Oscar Toledo G. for the 19th IOCCC (2006).

Variants

2 variants of the emulator are available:

  • i8080.ash loads the specified program into memory, where the memory is implemented by 65536 individual shell variables
  • i8080-rw.ash directly reads and updates the specified memory file in-place; one example usecase is to use /dev/fb0 as memory; because every memory access runs an external hexdump(1) or dd(1) command, memory performance will be poor.

Supported shells

Any POSIX-compatible Almquist shell is supported, this excludes ancient pre-POSIX versions of Almquist shell.

GNU bash 2.0 or later is also supported, but a reduced performance is expected.

It may work with other Unix shells, but this is not guaranteed.

Primarily tested with the Almquist shell provided by FreeBSD (/bin/sh) and Debian (/bin/dash).

dash versions 0.5.7 and later, and busybox ash are known to have suboptimal performance.

Other dependencies

In addition to a supported shell, some other basic external commands are required by the emulator:

  • dd(1)
  • hexdump(1)
  • grep(1)
  • perl(1)
  • stty(1), if using from a terminal (the usual case)

Supporting files

Usage

Both variants accept a single path name to the memory image file. Because i8080-rw.ash updates the memory image file in-place, it is recommended to first duplicate the memory image file, when trying out this variant.

If environment variables A, B, C, D, E, H, L, SP, PC and FLAGS are set to appropriate values, they will used for as the initial values of the respective registers to start emulation; this can be used to restore a previously interrupted emulation.

When running the emulator, pressing Ctrl-C will giving a menu for different actions. If you choose to dump registers and terminate emulation, you will be able to restore this emulation state by setting the register values in environment variables, as described above.

Examples

sh i8080.ash c_bios.bin
cat c_bios.bin > /dev/fb0
sh i8080-rw.ash /dev/fb0
A=0 B=0 C=255 D=77 E=255 H=238 L=212 SP=61245 PC=64277 FLAGS=84 sh i8080.ash my-last-save

Transfer files into virtual disk image

This emulator did not implement the file import support as available in Toledo‘s emulator. You will have to use Toledo’s emulator for this task, if needed.

You may follow the instructions on https://www.ioccc.org/2006/toledo2/index.html or https://web.archive.org/web/20120112040347/http://nanochess.110mb.com/emulator.html to transfer files into your virtual disk images.

History

The initial work of this project was began in 2021, as improvements to the i8080 emulater in bash that written by NASZVADI Peter. The improvements I made include bug fixes for existing instructions, implementation of new instructions, and disk I/O support, to enable the emulator to correctly run CP/M, as well as Zork I for CP/M; other added features include significantly faster loading of user-specified memory image file, advanced Ctrl-C handling including memory dump support, ability to save and restore of emulation state, and an alternative variant for direct memory file access (for playing with /dev/fb0).

I was excited to demonstrate this version at the time; the result is this video on YouTube, Zork, CP/M running on BASH, with /dev/fb0 as memory.

However, there a serious issue with the original program by NASZVADI Peter; it did not came with a license, to enable 3rd-party distribution permission for the program! Unfortunately the original author refused to license it, so sadly the program remains proprietary to this day.

The solution? Rewrite the entire emulation logic from scratch! This move also provided a bonus that I was able to target the program to Almquist shell instead of bash; this creates a significant performance advantage over the old proprietary implementation, if an efficient implementation of Almquist shell is used, such as FreeBSD ash or dash 0.5.5.1.

License

Source files i8080.ash and i8080-rw.ash are distributed under the Mozilla Public License, version 2.0; a copy of this license is provided as COPYING file.

Binary files c_basic.bin and c_bios.bin are distributed under Creative Commons Attribution-ShareAlike 4.0 International license.