honesty
is a NES emulator written in Haskell. Very much a WIP.
Perhaps it's named for "Haskell un-Optimized NES emulator using TYpes"
I'm writing it for fun, and to get more experience in how best to structure a reasonably complicated Haskell application.
During the development, I've fallen into a style of describing Effect
s for different parts of the system, which get wired together using inter
preter functions. Often the interpreter for one kind of effect will cause further effects.
Where possible I am using good old fashioned functional/persistent state, for example for the state of the CPU and PPU registers. For the larger 2k-Rams I am interpreting their effects in IO
to make use of mutable arrays.
The 6502 emulator is done. And matches the golden log for the nestest.nes
rom. And the remaining system (PPU Registers, NMI, OAM, DMA, Rendering, Controller, etc) is just about complete enough to allow Donkey Kong to run, albeit rather slowly.
For a more detailed description of the development progress, see the developer log.
There is still much todo:
- Increase speed: Currently it runs at about 1/3 speed required.. UPDATE: now about 3/4 speed
- Improve sprite rendering to properly support sprite overlap
- Add cycle-count to DMA (currently this happens in 0-time!)
- Revisit the spec for the PPU regs:
PPUCTRL
,PPUMASK
,PPUSTATUS
-- done - Support sprite-0 collision
- Support sprite overflow
- Nametable mirroring
- Scrolling
- Mappers
- PPU cycle accuracy
- Sound, maybe!
Also: Make something other than DK work! -- YES, ballon fight
And the nestest
rom and log from
here.
- OpCode <-> Instruction/Addressing-Mode mapping Used as the basis of my Opcode.hs.
- Flag effects & cycle times Easiest navigation.
- Status Flags behaviour Including details of the mysterious B-flag!
- Subtraction on the 6502 "SBC simply takes the ones complement of the second value and then performs an ADC."
- Overflag flag following ADC/SBC "( (A ^ s) & (v ^ s) & 0x80 )."
- Dustmop on NES graphics: part 1, part 2, and part 3
- Austin Morlan on NES rendering
- Colours: RGB mapping
./test.sh
stack run -- --speed
stack run
stack run -- --dis
stack run -- --emu (6502 only)
stack run -- --tiny
stack run -- --full
stack run -- --full --fps 45
stack run -- --full --fps 45 path/to/rom
The standard NES controller had 8 buttons: Up, Down, Left, Right, A, B, START, SELECT.
These are mapped to the keyboard as:
Up
: UpDown
: DownLeft
: LeftRight
: Rightz
: Ax
: BEnter
: STARTTab
: SELECT
Escape
: quitSpace
: pause simulationF1
: cycle LHS display (initially blank):F2
: cycle RHS display (initially full display: playfield + sprites)F3
: toggle active sprite displayF4
: toggle fps/skipped/frame# displayF5
: toggle buttons pressed displayF6
: toggle PPU regs (Control/Mask) display
The display mode cycles though various debug displays and the full display:
- Blank
- Attribute table palette selection
- Just playfield
- Just sprites (on an empty background)
- Combined playfield & sprites