Rust 6502
- 44 Devlogs
- 36 Total hours
A MOS-6502 Emulator written in Rust
A MOS-6502 Emulator written in Rust
Last devlogs before Ship #1 
Wow 37h of work.
I have made an Asciinema video, Youtube video and update the README.md
Wish me luck !
I have been writing a LOT of documentation on how to create a 6502 ASM program, Screen documentation. And the project is now published in version 1.0.0 on Github and Cargo
I have added a new program called HackClub Logo 
First, I have draw the hackclub logo in aseprite with a 32x32 pixel file using my custom color palette.
Second, I have created a simple python script who take a .png in input and output ASM raw data for the image (using my color palette).
Third, I have create a simple ASM program to print the logo on the screen !
WOW 35H 🎉
I have added a file : DemoProgram.md to show all the demo program
WOW 4h 😅
I have done the full README.md, documentation about the screen, color palette and fix some little bugs.
Little bug fix: Now when we select a file in the Home File Selector the filename appear in the Opcode container.
I have also reorganize the tui.rs code !
WOW already 30 hours ?! 😅
I now have added the home logo ! I also changed the step for the speed selection on Home Menu from 500 to 100 for each step
Wow that was damn hard 😭. But the Home Menu is finally here 🎉. There is the logo (might change). The select file container with full navigation (folder, parent directory, file), Icon (require a Nerd Font) and Colors. The selected file path update in real time with the absolute path of the file. The start address automatically change if the file selected is a demo file (end with “_demo.bin”) to $C000. The start address it editable with Alpha numeric character (hexadecimal). And the emulation speed work ! There is control on the footer bar.
New demo program… HelloWorld_demo !
Print Hello World ! centered on the screen all in pure 6502 Assembly. I also modified the way the disassembler work, now even if there is a BRK it will continue to read the file until the end. The ASM part was really really haaarrddd.
Now if I press R I can reset the program. I also modify the footer bar
I have update the color from word to RGB value so if a different terminal theme is applied the color are the same. I also added a footer bar with the keybinds.
New panel 🥁🥁🥁…. the ✨ SETTINGS ✨ !
In this panel there is a smaller version of the Logo and the settings to modify the speed of the CPU. There is also the link to the github repo and stardance project
Now the name of the file currently running is in the title. I also finished the rainbow program to fill the whole screen.
New feature 🥁🥁🥁 ✨ THE SCREEN ✨ This was very very hard. The screen use the Unicode half-block character “▀”, to write to the screen you just need to send value like this :
LDA #$02 ; load "02" into the accumulator
STA $0200 ; store it at memory address $0200 (the 1st pixel)
Here the 02 is the color RED.
Here is the color palette:
fn palette_color(index: u8) -> Color {
match index & 0x0F {
0 => Color::Black,
1 => Color::White,
2 => Color::Red,
3 => Color::Cyan,
4 => Color::Magenta,
5 => Color::Green,
6 => Color::Blue,
7 => Color::Yellow,
8 => Color::Rgb(255, 165, 0), // Orange
9 => Color::Rgb(153, 76, 0), // Brown
10 => Color::DarkGray,
11 => Color::Gray,
12 => Color::LightRed,
13 => Color::LightBlue,
14 => Color::LightGreen,
_ => Color::Reset, // 15 transparent
}
}
The color may vary between terminal theme.
I also had created an ASM program to print a rainbow on the 1st quarter of the screen.
I also added the feature that when a BRK instruction is hit the program turn to HALT mode (in the UI).
I also added the indentation system to BEQ, BNE, BCC, BCS, BMI, BPL, BVC, BVS.
I also added a new way of calculating the speed of the program.
Choosing between a variety of logo (2 first screen shot are in Apple Terminal the last is in ghostty with a Catpuccin Mocha theme)
I have added a top bar in the memory container with the last part of the address (to be more easy to read).
I also fixed all the scroll bar from scrolling outside the container and just see nothings
I have fixed the cursor in the Stack Container to scroll automaticly when needed and when running. I also optimised the code !
A lot has been going on
! I have added the Memory Viewer, Scroll bar to the Stack Viewer and Memory Viewer (work with the 🥁…. SCROLL WHEEL !). I also reduce the space taken by the opcode list so we can see the memory viewer !
I have added a Stack Viewer on the left ! The container scroll it self when the “cursor”/current position of the Stack Pointer (SP). I also have fix the text for the SP in the register container
I have tried to implement multi-threading but realize that it’s not worth it for a simple emulator like this one.
I have clean the code a little bit 🧹 and added a RUN or PAUSED indicator :
The UI is going forward one step after another ! 
I have changed a some little like the place where is the Flag Container, now it’s on the left side.
And I also have added a LOT a things like:
Things I have removed:
YAY
now the Flags can be shown ! Green Bold when active and Dark Gray classic when not
I have made a program to disassemble the program so the code could be shown in the TUI. And it work ! 
I am now making the TUI part of this emulator ! I am using Ratatui to make the TUI. This mean I have to change all the printing part of my existing program
YAY
Now EVERY opcode and EVERY addressing mode are implemented 🎉
(wow 1478 lines of pure opcodes)
I have fix some little print in 3-4 instruction and the IRQ function
I’m being closer and closer of getting all opcode and all Addressing mode implemented 
Here are the list of opcode I have implemented and there Addressing Mode:
I also fixed the CLD instruction. I was doing a :
cpu.sr |= !CPU::DECIMAL_FLAG;
but the right one was this:
cpu.sr &= !CPU::DECIMAL_FLAG;
New opcode time ! 
LDY
STA
STX
STY
Add interruption with NMI + IRQ.
Add option to the user to start at a specific address
New opcode 
I’ve just passed 40min to fix an interruption problem to final look back and see that my original code what working perfectly fine 😭 . I’ve also change my build tools to ca65 + ld65
YAY
I have added a BUNCH of new Opcodes
:
New opcode 
New Addressing Mode:
✨ NEW OPCODE ✨
:
But I have also add a memory dump with page (at the end of a program) to debug ! (1st screenshot) and i also add a fixed (address) memory viewer when running (2nd screenshot)
There now is 4 new opcode:
New Opcode :
The now is new opcode ! :
And some new AddressingMode :
Now there is a pop_stack function who return the top value of the stack (Last In First Out).
I’ve also added those opcode :
And made this test code :
I’ve done a LOT of work.
Added Opcodes:
I’ve also done a lot of refractorisation. Code before :
match opcode {
0x18 => {
self.sr &= !CPU::CARRY_FLAG;
self.set_instr(format!("{:02X}", opcode), "CLC".to_string(), 2);
},
// ...
}
VS now :
match opcode {
0x18 => self.clc(opcode),
// ...
}
So now every opcode have his own function !
I’ve added those instruction:
I’ve also made this little ASM 6502 program to test those opcode
.org $8000
START:
SEC ; to test CLC
LDA #$FF ; A = 255
CLC ; Clear Carry Flag before addition
ADC #$02 ; 255 + 2 = 1, Carry is now 1 (0x01FF + 0x0002 = 0x0201)
STA $20 ; Store Low Byte result (01) at $20
LDA #$00 ; Load 0 for the high byte
ADC #$00 ; 0 + 0 + 1 (Carry from previous instruction) = 1
STA $21 ; Store High Byte result (01) at $21
; SEC use
SEC ; Carry = 1
LDA #$01 ; A = 1
ADC #$00 ; 1 + 0 + 1 (Carry) = 2
BRK
And it work just fine !
I’ve added a bunch of opcode like : STA, STX, STY (Zero Page, Absolute) LDX, LDY (Immediate, Zero Page, Absolute) JMP (Absolute), JMP (Indirect) (the screen shot is a new program that i’ve made and test on virtual 6502 and my project)
I’ve added a new UI and AddressingMode
Hi ! Right now in my project I have added :
Bus with ram
CPU
(1st screenshot is official emulator 2nd is mine)