Rust 6502
- 63 Devlogs
- 74 Total hours
A MOS-6502 Emulator written in Rust, and with a custom TUI !
A MOS-6502 Emulator written in Rust, and with a custom TUI !
+1h20
So… this might be the last devlog for this project. I just released the v1.3.0. And here is what I added since the last devlog :
So next step is the 3rd Ship

+ 1h35
! This might be the last feature I add to Rust 6502. Since I ran out of idea and for me the project seem to be finished.
Anyway, here are the things I added :
+1h 25 min ! Since the last time I have added the keybind panel. Where there is… all the keybinds 
I also remove the keybind on the footer to only get Keybind “K”
As a prize for your great work, look out for a bonus prize in the mail :)
Okay so… I have added the Breakpoint and the Watchpoint
. When you set the breakpoint to $C00C the CPU will stop before running the instruction at $C00C. The watchpoint stop if a value at an address at been changed.
I added the step-back function. It work by pressing “B”, it’s just rewinding the emulator up to 500 opcode. Only work when moving in step-by-step mode (with Enter)
YAY
Now rust6502 Version 1.1.0 is released ! On github with all the demo file and on crates.io / cargo !
Here is what I have done in 2h 50
. First I wrote a lot of docs, for the keyboard, Serial Monitor, Wozmon etc… This was so boring
. But at least now I will be ready to ship soon !
Second, I have fixed the Wozmon list content of address. Before when you was doing FF00.FFFF it was just showing the byte at $FF00 and the byte at $FFFF now it list all the byte between !
New little update ! I have created a Python tools to create memory map for my emulator docs !
Little update ! I have added tips in the settings menu. The change randomly using the UNIX Epoch value
Little update, I added a Program Counter (PC) input to move it in when running a program. I also added a cursor for the start input on the Home Screen ! 
After 1h50
I have added a Snake demo program that use the PS/2 keyboard !!!
I also make a demo program to test the Serial Monitor using netcat nc
Wow, just WOW. I have added a serial monitor, and Apple 1 OS 
Here is the way the monitor work, you load character to $BFE0 like this :
lda #'A'
sta $BFE0
Then you run the program in the emulator like normal, then you open another terminal and you connect to localhost port 8080 using netcat nc
like this :
nc 127.0.0.1 8080
And now if you already launch the program, when you connect to localhost (127.0.0.1 is localhost) you will see a A in your terminal !
You can also type in the serial monitor ! Here is a code that show the number of characters typed by using the pixels in the 32x32 screen !
start:
ldx #$FF
txs
ldx #$00
main_loop:
bit $BFE1
bpl main_loop
lda $BFE0
sta $BFE0
lda #WHITE_COLOR
sta $0200, x
inx
jmp main_loop
This is a very damn big part.
To be short, I have recreated the Apple 1 OS (Wozmon) created by Steve Wozniak. In short I took the code given in the Apple 1 User Manual, modify it to use the Serial Monitor and Keyboard, fix some issue with the prompt. I can even run the classic program from the manual to print all the available characters.
With Wozmon you can also write and read data from the memory so you can show some pixel on the screen !
Here is the program running and the serial monitor.
Okay soo….. it’s been 4 hours and 35 minutes
. I have done so much and not that much at the same time (I know it’s weird
) I have added a demo program who print the pressed character ! I have spend 2 hours on a little bug
but yeah now it’s working ! So with the program I drew all the key on a PS/2 keyboard
. I also fixed some little inattention problem in my code.
I also created a little python script to help me convert .png drawing into raw .inc value ! 
( Did you find the secret phrase ?)
Now there is all the number & lower case letter (a-z) & and the Space bar icon ! 
I want to create a ASM program who print the pressed key to the screen, and for that I need to create the font/image for each key. There is ~100 key
. So here is the first one ! 
Wow that was… difficult
. But now there is a PS/2
keyboard Emulation
! 
The I/O port is map on $BFF0-$BBF2. The PS/2 keyboard work with 3 addresses
To activate to keyboard in the emulator you can press on the screen container and to exit it just click anywhere else !
(The number you can see in the memory viewer at $0000 is the code from different key !)
Maybe next time I will create a program to see each letter
YAY
! Now there is
mouse control on the home screen, this mean that you can click every where to change the focus and in the file explorer you can double-click to open a folder and double-click to open a file directly, you can also with a simple click enable or disable Force Address Mode
Ok so… it’s been 8h40
.
I have done a lot (I mean it’s logic it’s been 8h and 40 minutes)
In time order I have done :
Replace self.pc + 1 to self.pc.wrapping_add(1) so it’s like on the real 6502 if the current PC is $FFFF and you add 1 it will be $0000.
Added a panic hook, before when the program was crashing (for a bad ASM program by example) the terminal was still in RAW mode (so if you click, move the mouse etc… it will print a bunch of garbage number) but now it exit the raw mode in a clean way !
Remove unused import
Change the start of the Stack Pointer to $1FFF
Added a memory reset function
Write a bunch of test programs 
Replace IPS (instruction per seconds) by Hz and MHz like in real life
(so i’ve adapted the UI for the change)
Now the disassembler disassemble the whole program (neat right ?
) using .len(). (yes before it was an hard-coded number 
Optimize the screen render method. Before I was refreshing the screen even if nothings has been changed, now i check if somethings have been changed to update the screen 
Added address of each “quarter” of the screen in the screen documentation 
Fixed foreground and background color of the Frequency selector (on the Home Screen)
Write a program to test IRQ and NMI
Keybinds the I and N key to IRQ and NMI 
Changed the Hello World program to be rainbow 
The emulator will look by it self to the reset vector ($FFFC and $FFFD) to set the PC at the correct address
Added a force address toggle to… force the the start address
When the force addr toggle is off you can’t modify the start Addr and it’s darker
Every file or folder who start by a . (dot) is not shown in the file selector 
Moved the hackclub logo raw binary data to a .inc file 
Added a self crashing test program 
(Next time I might add a PS/2 keyboard emulation…
)
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)