Skip to content

Latest commit

 

History

History
166 lines (127 loc) · 5.08 KB

README.md

File metadata and controls

166 lines (127 loc) · 5.08 KB

ci

MOS6502

This is a toy project where I've created an emulator, assembler and a disassembler for the 1975 8-bit MOS 6502 CPU.

asciicast of TUI emulator

$ ./mos6502
Usage: mos6502 [OPTIONS] <COMMAND>

Commands:
  assemble     Assemble a program
  disassemble  Disassemble a binary file
  emulate      Run a program in the emulator
  help         Print this message or the help of the given subcommand(s)

Options:
      --trace
          Enable chrome tracing which on program exit will generate
          a json file to be opened with a chrome tracing compatible
          viewer.

  -h, --help
          Print help (see a summary with '-h')

  -V, --version
          Print version

Assembling

Example program

The assembler supports the syntax found at Nick Morgan's Easy6502 which looks something like the program below.

Here's a program which increments memory address 0x00 ten times.

define counter $00  ; Address of counter
define max 10       ; Num of times to loop

.org $8000

main:
  jsr init          ; Initialize counter
  jsr loop          ; Run loop
  jmp exit          ; Exit program

init:
  lda #0            ; Load 0 into accumulator
  sta counter       ; Store accumulator into counter address
  rts

loop:
  lda counter       ; Load what's in counter address into accumulator
  cmp #max          ; Compare accumulator to max value
  beq done          ; If equal, branch to done
  inc counter       ; Increment counter
  jmp loop          ; Jump to loop
done:
  rts               ; Return back to main

exit:
  jmp exit          ; Infinite loop

To assemble the program into machine code we can run it through the assembler:

$ cargo run -r -- assemble examples/loop.asm -o loop.bin

Disassembling

The disassembler can parse the assembled binary and list the instructions in the program.

$ cargo run -r -- disassemble loop.bin
   Compiling mos6502 v0.1.0 (/home/david/Dev/mos6502)
    Finished release [optimized] target(s) in 0.07s
     Running `target/release/mos6502 disassemble loop.bin`
 Addr  Hexdump   Instructions
-----------------------------
0x0000  00        BRK
*
0x8000  20 09 80  JSR $8009
0x8003  20 0e 80  JSR $800E
0x8006  4c 1a 80  JMP $801A
0x8009  a9 00     LDA #$00
0x800b  85 00     STA $00
0x800d  60        RTS
0x800e  a5 00     LDA $00
0x8010  c9 0a     CMP #$0A
0x8012  f0 05     BEQ $05
0x8014  e6 00     INC $00
0x8016  4c 0e 80  JMP $800E
0x8019  60        RTS
0x801a  4c 1a 80  JMP $801A

Emulation

To run the assembled program we can invoke the emulator command. By default a graphical interface is opened (See screencast up above).

$ cargo run -r -- emulate loop.bin

If the file passed to the emulator is a file with assembly code, the program will be assembled and run automatically.

Supported assembler syntax

Syntax type Example
Instructions (Mnemonic with operands) JSR main, LDA $00
Comments ; A comment
Hex literals $ff, $8000
Binary literals %1101, %10110000
Decimal literals 42, 4096
Immediate values #42, cmp #max
Labels main:
Constants define max $ff, define screen_width 40
Org directives .org $8000

Future development

  • Assembler
    • dot directives
      • .org $8000
      • .byte 42
      • .word $8000
    • #"A"
    • Operand arithmetics
  • Emulator
    • Peripherals - I/O would be fun to have...
    • Decimal mode
    • Stack overflow detection
  • TUI
    • Load file with l
    • Centered disassembler view
    • Contiuous run with screen update

References

I've found many great resources and project which helped this project, here are a few