I really like your tutorial. I been trying to learn assembly and your tutorial is really helping me put the big picture together. I hope you continue to work on making it better.
There are two sensible approaches: interpretation or dynamic translation.
If you want to write one as a learning experience for how the platform you're emulating works and how an emulator could work in principle, you probably want to write an interpreter: find out how the platform boots, build something to start reading and interpreting instructions, start adding emulated hardware devices, and you'll get an increasingly functional interpreter.
For a start, you could ignore emulation of devices, and just write a CPU core that interprets instructions.
If you want to learn how modern (but still non-hardware-assisted) emulation works, read about how qemu's dynamic code translator and other JIT compilers work, and build a CPU emulator based on that.
I'm not the OP but check out the book: "The Elements of Computing Systems: Building a Modern Computer from First Principles" It's quite comprehensive, not exactly about writing an emulator, but it should give you what you need.