I wanted to learn 6502 Assembly so began exploring different resources. I first came across Nick Morgan's
6502 tutorial [1], which I found to be very helpful for grasping the basics. However, I quickly hit a wall and began exploring different Assembly resources, C64 literature as well as Assembly for Zilog z80, Sharp LR35902 (Gameboy), Motorolla 68k (Sega Genesis). I found myself coming back to 6502 when I found Dave Poo's [2] video on reverse engineering the 6502 to make an emulator in C++. After watching Dave's process for creating instructions in C++ ( Read instruction definitions [3], code the functionality, run tests to ensure the instruction works as it is supposed to), I decided the best way to learn would be to move away from the 'Copy along' coding and just follow his methods to do it myself. I chose to do it in Javascript as I remembered Morgan's tutorial and liked how interactive the whole experience was.
This is the product of this CPD exercise.
This project is not original in idea, but its not copied code either. The aim here is purely a learning exercise.
The main focus of this project is the CPU instructions. All of the CPU instructions are now emulated.
I wanted to make my own UI and not just copy Morgan's. While his had all of the information available, I found myself wanting more from the UX when using Morgan's tutorials. Consequently, I made my own memory monitor, which has byte highlighting and also ASCII character translation of bytes. My monitor always returns 256 bytes (where possible) and has (in my opinion) a clearer program status output. However Morgan's app is designed to have multiple instances on the same page, so neither solution is right, wrong, good or bad
The code for the screen is based on Morgan's implementation. I just transposed it into a TypeScript class as opposed to an inline function of functions. $0200-$05FF represent each pixel on the screen (32x32 - left to right, top to bottom).
The code editor now works as an assembler and can assemble code to bytes.
Currently, text can be entered and tab support is implemented based on Brad Robinson's StackOverflow answer [4]
Code entered into the text edito can be copied to clipboard
Code can be stepped through and progress of the program status can be monitored on each step.
The run button is currently disabled as code needs to be refactored so that running programs run on a separate task. This will prevent endless loops from locking up the browser.
There is a known issue with this code. At the top of ./js/cpu.js
the following code block must be commented out when running:
// @ts-expect-error - not a module - but this allows Jest test
import Flag from "./flag";
// @ts-expect-error - not a module - but this allows Jest test
import Instruction from "./instruction";
// @ts-expect-error - not a module - but this allows Jest test
import Register from "./register";
These lines are added so that I could get Jest to work. At the bottom of each file the follow line is also present:
module.exports = <CLASS_NAME>;
However classes are not exported. This causes a warning to appear in the console. Again, both of these solutions were done to get Jest working. Once I have finished developing this I will likely go back and try to solve the issue more directly, but for now I am able to run tests as I am developing and that's all that matters.
1 Morgan, N. (2020). skilldrick/easy6502. Retrieved 15 January 2021, from https://github.com/skilldrick/easy6502
2 Poo, D. (2020). Emulating a CPU in C++ (6502). Retrieved 1 February 2021, from https://www.youtube.com/watch?v=qJgsuQoy9bc
3 Jacobs, A. (2009) 6502 Introduction. Retrieved 1 February 2021, from http://www.obelisk.me.uk/6502/
4 Robinson, B. (2017). Use tab to indent in textarea - StackOverflow. Retreived 4 February 2021, from https://stackoverflow.com/a/45396754/2107659