Documentation ¶
Index ¶
- Constants
- Variables
- func ButtonName(button Button) string
- func IsNESFile(path string) bool
- func IsNSFFile(path string) bool
- func NewMemory(size int) []byte
- func PlayNSF(nsf NSFFile, track byte, audioOut chan []float32, sampleRate float32, ...) error
- type APUState
- func (apu *APUState) Copy() APUState
- func (apu *APUState) GenerateSample() float32
- func (apu *APUState) HalfFrame()
- func (apu *APUState) IsIRQAsserted() bool
- func (apu *APUState) QuarterFrame()
- func (apu *APUState) ReadStatus() byte
- func (apu *APUState) Run(apuCycles float64, cyclesPerSample float64, cpu *CPUState) []float32
- func (apu *APUState) WriteChannelEnable(value byte, cpu *CPUState)
- func (apu *APUState) WriteDMCAddress(value byte)
- func (apu *APUState) WriteDMCEnable(value byte)
- func (apu *APUState) WriteDMCLength(value byte)
- func (apu *APUState) WriteDMCLoad(value byte)
- func (apu *APUState) WriteFrameCounter(value byte)
- func (apu *APUState) WriteNoiseEnvelope(value byte)
- func (apu *APUState) WriteNoiseLength(value byte)
- func (apu *APUState) WriteNoiseMode(value byte)
- func (apu *APUState) WritePulse1Duty(value byte)
- func (apu *APUState) WritePulse1Length(value byte)
- func (apu *APUState) WritePulse1Sweep(value byte)
- func (apu *APUState) WritePulse1Timer(value byte)
- func (apu *APUState) WritePulse2Duty(value byte)
- func (apu *APUState) WritePulse2Length(value byte)
- func (apu *APUState) WritePulse2Sweep(value byte)
- func (apu *APUState) WritePulse2Timer(value byte)
- func (apu *APUState) WriteTriangleCounter(value byte)
- func (apu *APUState) WriteTriangleTimerHigh(value byte)
- func (apu *APUState) WriteTriangleTimerLow(value byte)
- type Button
- type ButtonMapping
- type CPUState
- func (cpu *CPUState) BRK()
- func (cpu *CPUState) Compare(other *CPUState) error
- func (cpu *CPUState) ComputeIndirectX(relative byte) uint16
- func (cpu *CPUState) ComputeIndirectY(relative byte) (uint16, bool)
- func (cpu *CPUState) Copy() CPUState
- func (cpu *CPUState) Equals(other CPUState) bool
- func (cpu *CPUState) Execute(instruction Instruction) error
- func (cpu *CPUState) Fetch(table InstructionTable) (Instruction, error)
- func (cpu *CPUState) GetCarryFlag() bool
- func (cpu *CPUState) GetDecimalFlag() bool
- func (cpu *CPUState) GetInterruptDisableFlag() bool
- func (cpu *CPUState) GetMemoryPage(address uint16) []byte
- func (cpu *CPUState) GetNegativeFlag() bool
- func (cpu *CPUState) GetOverflowFlag() bool
- func (cpu *CPUState) GetZeroFlag() bool
- func (cpu *CPUState) Interrupt()
- func (cpu *CPUState) IsIRQAsserted() bool
- func (cpu *CPUState) Load(other *CPUState)
- func (cpu *CPUState) LoadMemory(address uint16) byte
- func (cpu *CPUState) LoadStack(where byte) byte
- func (cpu *CPUState) MapMemory(location uint16, memory []byte) error
- func (cpu *CPUState) NMI()
- func (cpu *CPUState) PopStack() byte
- func (cpu *CPUState) PushStack(value byte)
- func (cpu *CPUState) Reset()
- func (cpu *CPUState) Run(table InstructionTable) error
- func (cpu *CPUState) SetBreakFlag(set bool)
- func (cpu *CPUState) SetCarryFlag(set bool)
- func (cpu *CPUState) SetDecimalFlag(set bool)
- func (cpu *CPUState) SetInterruptDisableFlag(set bool)
- func (cpu *CPUState) SetMapper(mapper Mapper)
- func (cpu *CPUState) SetNegativeFlag(set bool)
- func (cpu *CPUState) SetOverflowFlag(set bool)
- func (cpu *CPUState) SetStack(location uint16)
- func (cpu *CPUState) SetZeroFlag(zero bool)
- func (cpu *CPUState) Stall(cycles int)
- func (cpu *CPUState) StoreMemory(address uint16, value byte)
- func (cpu *CPUState) StoreStack(where byte, value byte)
- func (cpu *CPUState) String() string
- func (cpu *CPUState) UnmapAllProgramMemory()
- func (cpu *CPUState) UnmapMemory(address uint16, length uint16) error
- type DMC
- type Divider
- type EnvelopeGenerator
- type HostInput
- type Input
- type Instruction
- type InstructionDescription
- type InstructionReader
- type InstructionTable
- type InstructionType
- type JustKind
- type LengthCounter
- type Mapper
- func MakeMapper(mapper uint32, programRom []byte, chrMemory []byte) (Mapper, error)
- func MakeMapper0(bankMemory []byte) Mapper
- func MakeMapper1(bankMemory []byte, chrMemory []byte) Mapper
- func MakeMapper2(bankMemory []byte) Mapper
- func MakeMapper3(programRom []byte, chrMemory []byte) Mapper
- func MakeMapper4(programRom []byte, chrMemory []byte) Mapper
- func MakeMapper7(programRom []byte, chrMemory []byte) Mapper
- func MakeMapper9(programRom []byte, chrMemory []byte) Mapper
- func MakeNSFMapper(data []byte, loadAddress uint16) Mapper
- type Mapper0
- type Mapper1
- func (mapper *Mapper1) Compare(other Mapper) error
- func (mapper *Mapper1) Copy() Mapper
- func (mapper *Mapper1) IsIRQAsserted() bool
- func (mapper *Mapper1) Kind() int
- func (mapper *Mapper1) Read(address uint16) byte
- func (mapper *Mapper1) ReadBank(pageSize uint16, bank int, offset uint16) byte
- func (mapper *Mapper1) Write(cpu *CPUState, address uint16, value byte) error
- type Mapper2
- type Mapper3
- type Mapper4
- func (mapper *Mapper4) CharacterBlock(length uint32, page byte) []byte
- func (mapper *Mapper4) Compare(other Mapper) error
- func (mapper *Mapper4) Copy() Mapper
- func (mapper *Mapper4) IsIRQAsserted() bool
- func (mapper *Mapper4) Kind() int
- func (mapper *Mapper4) ProgramBlock(page byte) ([]byte, error)
- func (mapper *Mapper4) Read(address uint16) byte
- func (mapper *Mapper4) ReadBank(offset uint16, bank int) byte
- func (mapper *Mapper4) Scanline()
- func (mapper *Mapper4) SetChrBank(ppu *PPUState) error
- func (mapper *Mapper4) Write(cpu *CPUState, address uint16, value byte) error
- type Mapper7
- func (mapper *Mapper7) Compare(other Mapper) error
- func (mapper *Mapper7) Copy() Mapper
- func (mapper *Mapper7) IsIRQAsserted() bool
- func (mapper *Mapper7) Kind() int
- func (mapper *Mapper7) Read(address uint16) byte
- func (mapper *Mapper7) ReadBank(address uint16, bank int) byte
- func (mapper *Mapper7) Write(cpu *CPUState, address uint16, value byte) error
- type Mapper9
- func (mapper *Mapper9) CharacterBlock(pageSize uint16, register byte) []byte
- func (mapper *Mapper9) Compare(other Mapper) error
- func (mapper *Mapper9) Copy() Mapper
- func (mapper *Mapper9) IsIRQAsserted() bool
- func (mapper *Mapper9) Kind() int
- func (mapper *Mapper9) Read(address uint16) byte
- func (mapper *Mapper9) ReadBank(offset uint16, bank int) byte
- func (mapper *Mapper9) SetChrBank(ppu *PPUState)
- func (mapper *Mapper9) Write(cpu *CPUState, address uint16, value byte) error
- type MapperState
- type Memory
- type NESFile
- type NSFActions
- type NSFFile
- type NSFMapper
- func (mapper *NSFMapper) Compare(other Mapper) error
- func (mapper *NSFMapper) Copy() Mapper
- func (mapper *NSFMapper) IsIRQAsserted() bool
- func (mapper *NSFMapper) Kind() int
- func (mapper *NSFMapper) Read(address uint16) byte
- func (mapper *NSFMapper) Write(cpu *CPUState, address uint16, value byte) error
- type NametableMirrorConfiguration
- type NoInput
- type Noise
- type PPUState
- func (ppu *PPUState) ConstructVideoAddress(fineY byte, nametable byte, coarseY byte, coarseX byte) uint16
- func (ppu *PPUState) ControlString() string
- func (ppu *PPUState) Copy() PPUState
- func (ppu *PPUState) CopyCharacterRom(base uint32, data []byte)
- func (ppu *PPUState) CopyOAM(data []byte)
- func (ppu *PPUState) DeconstructVideoAddress() (byte, byte, byte, byte)
- func (ppu *PPUState) GetBackgroundPatternTableBase() uint16
- func (ppu *PPUState) GetNMIOutput() bool
- func (ppu *PPUState) GetNameTableBaseAddress(index byte) uint16
- func (ppu *PPUState) GetNameTableIndex() byte
- func (ppu *PPUState) GetSpritePatternTableBase() uint16
- func (ppu *PPUState) GetSpriteSize() SpriteSize
- func (ppu *PPUState) GetSpriteZeroHit() bool
- func (ppu *PPUState) GetSprites() []Sprite
- func (ppu *PPUState) GetVRamIncrement() uint16
- func (ppu *PPUState) IncrementHorizontalAddress()
- func (ppu *PPUState) IncrementVerticalPosition()
- func (ppu *PPUState) IsBackgroundEnabled() bool
- func (ppu *PPUState) IsSpriteEnabled() bool
- func (ppu *PPUState) IsVerticalBlankFlagSet() bool
- func (ppu *PPUState) LoadBackgroundTile()
- func (ppu *PPUState) LoadNametableMemory(address uint16) byte
- func (ppu *PPUState) MaskString() string
- func (ppu *PPUState) PreloadTiles()
- func (ppu *PPUState) ReadOAM(address byte) byte
- func (ppu *PPUState) ReadStatus() byte
- func (ppu *PPUState) ReadVideoMemory() byte
- func (ppu *PPUState) RenderPixel(scanLine int, cycle int, sprites []Sprite, screen *VirtualScreen) bool
- func (ppu *PPUState) ResetHorizontalPosition()
- func (ppu *PPUState) Run(cycles uint64, screen VirtualScreen, mapper Mapper) (bool, bool)
- func (ppu *PPUState) SetControllerFlags(value byte)
- func (ppu *PPUState) SetHorizontalMirror()
- func (ppu *PPUState) SetMask(value byte)
- func (ppu *PPUState) SetOAMAddress(value byte)
- func (ppu *PPUState) SetScreenAMirror()
- func (ppu *PPUState) SetScreenBMirror()
- func (ppu *PPUState) SetSpriteZeroHit(on bool)
- func (ppu *PPUState) SetVerticalBlankFlag(on bool)
- func (ppu *PPUState) SetVerticalMirror()
- func (ppu *PPUState) StoreNametableMemory(address uint16, value byte)
- func (ppu *PPUState) ToggleDebug()
- func (ppu *PPUState) UpdateMapper4Scanline(mapper Mapper)
- func (ppu *PPUState) WriteAddress(value byte)
- func (ppu *PPUState) WriteOAM(value byte)
- func (ppu *PPUState) WriteScroll(value byte)
- func (ppu *PPUState) WriteVideoMemory(value byte)
- type Pulse
- type RecordInput
- type Sprite
- type SpriteSize
- type SquareSequencer
- type Sweep
- type Timer
- type Triangle
- type VirtualScreen
- func (screen *VirtualScreen) Area() int
- func (screen *VirtualScreen) Clear()
- func (screen *VirtualScreen) ClearToColor(red uint8, green uint8, blue uint8)
- func (screen *VirtualScreen) Copy() VirtualScreen
- func (screen *VirtualScreen) CopyFrom(copyFrom *VirtualScreen)
- func (screen *VirtualScreen) DrawPoint(x int32, y int32, rgb []uint8)
- func (screen *VirtualScreen) GetRGBA(x int, y int) (uint8, uint8, uint8, uint8)
Constants ¶
const ( Instruction_BRK InstructionType = 0x00 Instruction_ORA_indirect_x = 0x01 Instruction_KIL_1 = 0x02 Instruction_SLO_indirect_x = 0x03 Instruction_NOP_zero = 0x04 Instruction_ORA_zero = 0x05 Instruction_ASL_zero = 0x06 Instruction_SLO_zero = 0x07 Instruction_PHP = 0x08 Instruction_ORA_immediate = 0x09 Instruction_ASL_accumulator = 0x0a Instruction_ANC_immediate_1 = 0x0b Instruction_NOP_absolute = 0x0c Instruction_ORA_absolute = 0x0d Instruction_ASL_absolute = 0x0e Instruction_SLO_absolute = 0x0f Instruction_BPL = 0x10 Instruction_ORA_indirect_y = 0x11 Instruction_KIL_2 = 0x12 Instruction_SLO_indirect_y = 0x13 Instruction_NOP_zero_x = 0x14 Instruction_ORA_zero_x = 0x15 Instruction_ASL_zero_x = 0x16 Instruction_SLO_zero_x = 0x17 Instruction_CLC = 0x18 Instruction_ORA_absolute_y = 0x19 Instruction_NOP_1 = 0x1a Instruction_SLO_absolute_y = 0x1b Instruction_NOP_absolute_x_1 = 0x1c Instruction_ORA_absolute_x = 0x1d Instruction_ASL_absolute_x = 0x1e Instruction_SLO_absolute_x = 0x1f Instruction_JSR = 0x20 Instruction_AND_indirect_x = 0x21 Instruction_KIL_3 = 0x22 Instruction_RLA_indirect_x = 0x23 Instruction_BIT_zero = 0x24 Instruction_AND_zero = 0x25 Instruction_ROL_zero = 0x26 Instruction_RLA_zero = 0x27 Instruction_PLP = 0x28 Instruction_AND_immediate = 0x29 Instruction_ROL_accumulator = 0x2a Instruction_ANC_immediate_2 = 0x2b Instruction_BIT_absolute = 0x2c Instruction_AND_absolute = 0x2d Instruction_ROL_absolute = 0x2e Instruction_RLA_absolute = 0x2f Instruction_BMI = 0x30 Instruction_AND_indirect_y = 0x31 Instruction_KIL_4 = 0x32 Instruction_RLA_indirect_y = 0x33 Instruction_NOP_zero_x_1 = 0x34 Instruction_AND_zero_x = 0x35 Instruction_ROL_zero_x = 0x36 Instruction_RLA_zero_x = 0x37 Instruction_SEC = 0x38 Instruction_AND_absolute_y = 0x39 Instruction_NOP_2 = 0x3a Instruction_RLA_absolute_y = 0x3b Instruction_NOP_absolute_x_2 = 0x3c Instruction_AND_absolute_x = 0x3d Instruction_ROL_absolute_x = 0x3e Instruction_RLA_absolute_x = 0x3f Instruction_RTI = 0x40 Instruction_EOR_indirect_x = 0x41 Instruction_KIL_5 = 0x42 Instruction_SRE_indirect_x = 0x43 Instruction_NOP_zero_1 = 0x44 Instruction_EOR_zero = 0x45 Instruction_LSR_zero = 0x46 Instruction_SRE_zero = 0x47 Instruction_PHA = 0x48 Instruction_EOR_immediate = 0x49 Instruction_LSR_accumulator = 0x4a Instruction_ALR = 0x4b Instruction_JMP_absolute = 0x4c Instruction_EOR_absolute = 0x4d Instruction_LSR_absolute = 0x4e Instruction_SRE_absolute = 0x4f Instruction_BVC_relative = 0x50 Instruction_EOR_indirect_y = 0x51 Instruction_KIL_6 = 0x52 Instruction_SRE_indirect_y = 0x53 Instruction_NOP_zero_x_2 = 0x54 Instruction_EOR_zero_x = 0x55 Instruction_LSR_zero_x = 0x56 Instruction_SRE_zero_x = 0x57 Instruction_CLI = 0x58 Instruction_EOR_absolute_y = 0x59 Instruction_NOP_3 = 0x5a Instruction_SRE_absolute_y = 0x5b Instruction_NOP_absolute_x_3 = 0x5c Instruction_EOR_absolute_x = 0x5d Instruction_LSR_absolute_x = 0x5e Instruction_SRE_absolute_x = 0x5f Instruction_RTS = 0x60 Instruction_ADC_indirect_x = 0x61 Instruction_KIL_7 = 0x62 Instruction_RRA_indirect_x = 0x63 Instruction_NOP_zero_2 = 0x64 Instruction_ADC_zero = 0x65 Instruction_ROR_zero = 0x66 Instruction_RRA_zero = 0x67 Instruction_PLA = 0x68 Instruction_ADC_immediate = 0x69 Instruction_ROR_accumulator = 0x6a Instruction_ARR = 0x6b Instruction_JMP_indirect = 0x6c Instruction_ADC_absolute = 0x6d Instruction_ROR_absolute = 0x6e Instruction_RRA_absolute = 0x6f Instruction_BVS_relative = 0x70 Instruction_ADC_indirect_y = 0x71 Instruction_KIL_8 = 0x72 Instruction_RRA_indirect_y = 0x73 Instruction_NOP_zero_x_3 = 0x74 Instruction_ADC_zero_x = 0x75 Instruction_ROR_zero_x = 0x76 Instruction_RRA_zero_x = 0x77 Instruction_SEI = 0x78 Instruction_ADC_absolute_y = 0x79 Instruction_NOP_4 = 0x7a Instruction_RRA_absolute_y = 0x7b Instruction_NOP_absolute_x_4 = 0x7c Instruction_ADC_absolute_x = 0x7d Instruction_ROR_absolute_x = 0x7e Instruction_RRA_absolute_x = 0x7f Instruction_NOP_immediate = 0x80 Instruction_STA_indirect_x = 0x81 Instruction_NOP_immediate_2 = 0x82 Instruction_SAX_indirect_x = 0x83 Instruction_STY_zero = 0x84 Instruction_STA_zero = 0x85 Instruction_STX_zero = 0x86 Instruction_SAX_zero = 0x87 Instruction_DEY = 0x88 Instruction_TXA = 0x8a Instruction_STY_absolute = 0x8c Instruction_XAA = 0x8b Instruction_STA_absolute = 0x8d Instruction_STX_absolute = 0x8e Instruction_SAX_absolute = 0x8f Instruction_BCC_relative = 0x90 Instruction_STA_indirect_y = 0x91 Instruction_KIL_9 = 0x92 Instruction_AHX_indirect_y = 0x93 Instruction_STY_zero_x = 0x94 Instruction_STA_zero_x = 0x95 Instruction_STX_zero_y = 0x96 Instruction_SAX_zero_y = 0x97 Instruction_TYA = 0x98 Instruction_STA_absolute_y = 0x99 Instruction_TXS = 0x9a Instruction_SHY = 0x9c Instruction_STA_absolute_x = 0x9d Instruction_SHX = 0x9e Instruction_AHX_absolute_y = 0x9f Instruction_LDY_immediate = 0xa0 Instruction_LDA_indirect_x = 0xa1 Instruction_LDX_immediate = 0xa2 Instruction_LAX_indirect_x = 0xa3 Instruction_LDY_zero = 0xa4 Instruction_LDA_zero = 0xa5 Instruction_LDX_zero = 0xa6 Instruction_LAX_zero = 0xa7 Instruction_TAY = 0xa8 Instruction_LDA_immediate = 0xa9 Instruction_TAX = 0xaa Instruction_LAX_immediate = 0xab Instruction_LDY_absolute = 0xac Instruction_LDA_absolute = 0xad Instruction_LDX_absolute = 0xae Instruction_LAX_absolute = 0xaf Instruction_BCS_relative = 0xb0 Instruction_LDA_indirect_y = 0xb1 Instruction_KIL_10 = 0xb2 Instruction_LAX_indirect_y = 0xb3 Instruction_LDY_zero_x = 0xb4 Instruction_LDA_zero_x = 0xb5 Instruction_LDX_zero_y = 0xb6 Instruction_LAX_zero_y = 0xb7 Instruction_CLV = 0xb8 Instruction_LDA_absolute_y = 0xb9 Instruction_TSX = 0xba Instruction_LAS = 0xbb Instruction_LDY_absolute_x = 0xbc Instruction_LDA_absolute_x = 0xbd Instruction_LDX_absolute_y = 0xbe Instruction_LAX_absolute_y = 0xbf Instruction_CPY_immediate = 0xc0 Instruction_CMP_indirect_x = 0xc1 Instruction_DCP_indirect_x = 0xc3 Instruction_CPY_zero = 0xc4 Instruction_CMP_zero = 0xc5 Instruction_DEC_zero = 0xc6 Instruction_DCP_zero = 0xc7 Instruction_INY = 0xc8 Instruction_CMP_immediate = 0xc9 Instruction_DEX = 0xca Instruction_AXS = 0xcb Instruction_CPY_absolute = 0xcc Instruction_CMP_absolute = 0xcd Instruction_DEC_absolute = 0xce Instruction_DCP_absolute = 0xcf Instruction_BNE = 0xd0 Instruction_CMP_indirect_y = 0xd1 Instruction_KIL_11 = 0xd2 Instruction_DCP_indirect_y = 0xd3 Instruction_NOP_zero_x_4 = 0xd4 Instruction_CMP_zero_x = 0xd5 Instruction_DEC_zero_x = 0xd6 Instruction_DCP_zero_x = 0xd7 Instruction_CLD = 0xd8 Instruction_CMP_absolute_y = 0xd9 Instruction_NOP_5 = 0xda Instruction_DCP_absolute_y = 0xdb Instruction_NOP_absolute_x_5 = 0xdc Instruction_CMP_absolute_x = 0xdd Instruction_DEC_absolute_x = 0xde Instruction_DCP_absolute_x = 0xdf Instruction_CPX_immediate = 0xe0 Instruction_SBC_indirect_x = 0xe1 Instruction_ISC_indirect_x = 0xe3 Instruction_CPX_zero = 0xe4 Instruction_SBC_zero = 0xe5 Instruction_INC_zero = 0xe6 Instruction_ISC_zero = 0xe7 Instruction_INX = 0xe8 Instruction_SBC_immediate = 0xe9 Instruction_NOP_6 = 0xea Instruction_SBC_immediate_1 = 0xeb Instruction_CPX_absolute = 0xec Instruction_SBC_absolute = 0xed Instruction_INC_absolute = 0xee Instruction_ISC_absolute = 0xef Instruction_BEQ_relative = 0xf0 Instruction_SBC_indirect_y = 0xf1 Instruction_KIL_12 = 0xf2 Instruction_ISC_indirect_y = 0xf3 Instruction_NOP_zero_x_5 = 0xf4 Instruction_SBC_zero_x = 0xf5 Instruction_INC_zero_x = 0xf6 Instruction_ISC_zero_x = 0xf7 Instruction_SED = 0xf8 Instruction_SBC_absolute_y = 0xf9 Instruction_NOP_7 = 0xfa Instruction_ISC_absolute_y = 0xfb Instruction_NOP_absolute_x_6 = 0xfc Instruction_SBC_absolute_x = 0xfd Instruction_INC_absolute_x = 0xfe Instruction_ISC_absolute_x = 0xff )
const ( PPUCTRL uint16 = 0x2000 PPUMASK uint16 = 0x2001 PPUSTATUS uint16 = 0x2002 OAMADDR uint16 = 0x2003 OAMDATA uint16 = 0x2004 PPUSCROLL uint16 = 0x2005 PPUADDR uint16 = 0x2006 PPUDATA uint16 = 0x2007 OAMDMA uint16 = 0x4014 )
Special PPU memory-mapped locations
const ( APUPulse1DutyCycle = 0x4000 APUPulse1Sweep = 0x4001 APUPulse1Timer = 0x4002 APUPulse1Length = 0x4003 APUPulse2DutyCycle = 0x4004 APUPulse2Sweep = 0x4005 APUPulse2Timer = 0x4006 APUPulse2Length = 0x4007 APUTriangleCounter = 0x4008 APUTriangleIgnore = 0x4009 APUTriangleTimerLow = 0x400A APUTriangleTimerHigh = 0x400B APUNoiseEnvelope = 0x400c APUNoiseMode = 0x400e APUNoiseIgnore = 0x400d APUNoiseLength = 0x400f APUDMCEnable = 0x4010 APUDMCLoad = 0x4011 APUDMCAddress = 0x4012 APUDMCLength = 0x4013 APUChannelEnable = 0x4015 APUFrameCounter = 0x4017 APUStatus = 0x4015 // for reading )
APU memory-mapped locations
const ( INPUT_POLL = 0x4016 JOYPAD1 = 0x4016 JOYPAD2 = 0x4017 )
Input memory-mapped locations
const ( NametableMirrorVertical = iota NametableMirrorHorizontal NametableMirrorScreenA NametableMirrorScreenB )
const ( SpriteSize8x16 = iota SpriteSize8x8 )
const BRKVector uint16 = 0xfffe
const CPUSpeed float64 = 1.789773e6
http://wiki.nesdev.org/w/index.php/Cycle_reference_chart#Clock_rates * NTSC 2c0c clock speed is 21.47~ MHz ÷ 12 = 1.789773 MHz * Every second we should run this many cycles
const IRQVector uint16 = 0xfffe
const NMIVector uint16 = 0xfffa
const (
NSFActionTogglePause = iota
)
const OverscanPixels = 8
The number of pixels to hide on the top and bottom. Note * that the total visible height is VideoHeight-OverscanPixels*2
const ResetVector uint16 = 0xfffc
const VideoHeight = 240
const VideoWidth = 256
The standard size that the PPU will output
Variables ¶
var ApuDebug int = 0
var MaxCyclesReached error = errors.New("maximum cycles reached")
var TriangleWaveForm []byte = []byte{
15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
}
Functions ¶
func ButtonName ¶
Types ¶
type APUState ¶
type APUState struct { /* APU cycles, 1 apu cycle for every 2 cpu cycles */ Cycles float64 `json:"cycles"` /* frame sequencer clock, ticks at 240hz */ Clock uint64 `json:"clock"` /* if true then apu is in 4-step mode that generates interrupts * otherwise if false then apu is in 5-step mode with no interrupts */ FrameMode bool `json:"framemode"` UpdatedFrameCounter float64 `json:"framecounter"` InterruptInhibit bool `json:"interruptinhibit"` FrameIRQAsserted bool `json:"frameirq"` SampleCycles float64 `json:"samplecycles"` SampleBuffer []float32 `json:"samplebuffer"` SamplePosition int `json:"sampleposition"` Pulse1 Pulse `json:"pulse1"` Pulse2 Pulse `json:"pulse2"` Triangle Triangle `json:"triangle"` Noise Noise `json:"noise"` DMC DMC `json:"dmc"` EnableNoise bool `json:"enablenoise"` EnableTriangle bool `json:"enabletriangle"` EnablePulse2 bool `json:"enablepulse2"` EnablePulse1 bool `json:"enablepulse1"` }
func (*APUState) GenerateSample ¶
func (*APUState) HalfFrame ¶
func (apu *APUState) HalfFrame()
Half frame actions: length counters and sweep units
func (*APUState) IsIRQAsserted ¶
func (*APUState) QuarterFrame ¶
func (apu *APUState) QuarterFrame()
Quarter frame actions: envelope and triangle's linear counter
func (*APUState) ReadStatus ¶
func (*APUState) WriteChannelEnable ¶
func (*APUState) WriteDMCAddress ¶
func (*APUState) WriteDMCEnable ¶
func (*APUState) WriteDMCLength ¶
func (*APUState) WriteDMCLoad ¶
func (*APUState) WriteFrameCounter ¶
func (*APUState) WriteNoiseEnvelope ¶
func (*APUState) WriteNoiseLength ¶
func (*APUState) WriteNoiseMode ¶
func (*APUState) WritePulse1Duty ¶
func (*APUState) WritePulse1Length ¶
func (*APUState) WritePulse1Sweep ¶
func (*APUState) WritePulse1Timer ¶
func (*APUState) WritePulse2Duty ¶
func (*APUState) WritePulse2Length ¶
func (*APUState) WritePulse2Sweep ¶
func (*APUState) WritePulse2Timer ¶
func (*APUState) WriteTriangleCounter ¶
func (*APUState) WriteTriangleTimerHigh ¶
func (*APUState) WriteTriangleTimerLow ¶
type ButtonMapping ¶
type CPUState ¶
type CPUState struct { A byte `json:"a"` X byte `json:"x"` Y byte `json:"y"` SP byte `json:"sp"` PC uint16 `json:"pc"` Status byte `json:"status"` Cycle uint64 `json:"cycle"` /* holds a reference to the 2k ram the cpu can directly access. * this memory is mapped into Maps[] as well. Maps[] is redundant, * and can be removed at some point. */ Ram []byte `json:"ram,omitempty"` Maps [][]byte `json:"-"` StackBase uint16 `json:"stackbase"` PPU PPUState `json:"ppu"` APU APUState `json:"apu"` Debug uint `json:"debug,omitempty"` StallCycles int `json:"stallcycles,omitempty"` /* controller input */ Input *Input `json:"-"` Mapper MapperState `json:"mapper"` }
func StartupState ¶
func StartupState() CPUState
func (*CPUState) ComputeIndirectX ¶
func (*CPUState) ComputeIndirectY ¶
returns a new address and whether a page boundary was crossed
func (*CPUState) Execute ¶
func (cpu *CPUState) Execute(instruction Instruction) error
func (*CPUState) Fetch ¶
func (cpu *CPUState) Fetch(table InstructionTable) (Instruction, error)
func (*CPUState) GetCarryFlag ¶
func (*CPUState) GetDecimalFlag ¶
func (*CPUState) GetInterruptDisableFlag ¶
func (*CPUState) GetMemoryPage ¶
func (*CPUState) GetNegativeFlag ¶
func (*CPUState) GetOverflowFlag ¶
func (*CPUState) GetZeroFlag ¶
func (*CPUState) IsIRQAsserted ¶
func (*CPUState) LoadMemory ¶
func (*CPUState) Run ¶
func (cpu *CPUState) Run(table InstructionTable) error
func (*CPUState) SetBreakFlag ¶
func (*CPUState) SetCarryFlag ¶
func (*CPUState) SetDecimalFlag ¶
func (*CPUState) SetInterruptDisableFlag ¶
func (*CPUState) SetNegativeFlag ¶
func (*CPUState) SetOverflowFlag ¶
func (*CPUState) SetZeroFlag ¶
func (*CPUState) StoreMemory ¶
func (*CPUState) StoreStack ¶
func (*CPUState) UnmapAllProgramMemory ¶
func (cpu *CPUState) UnmapAllProgramMemory()
unmap the 32k block starting at 0x8000
type DMC ¶
type DMC struct { Irq bool `json:"irq"` Loop bool `json:"loop"` Frequency float64 `json:"frequency"` Counter float64 `json:"counter"` StartingAddress uint16 `json:"startingaddress"` Address uint16 `json:"address"` Length uint16 `json:"length"` BytesRemaining uint16 `json:"bytesremaining"` OutputLevel byte `json:"outputlevel"` IRQAsserted bool `json:"irqasserted"` Silence bool `json:"silence"` ShiftRegister byte `json:"shift"` BitsRemaining byte `json:"bitsremaining"` SampleBuffer byte `json:"samplebuffer"` }
func (*DMC) GenerateSample ¶
func (*DMC) LoadSample ¶
type Divider ¶
type Divider struct { /* how many input clocks must pass before an output clock is generated */ ClockPeriod uint16 `json:"period"` Count int16 `json:"count"` }
type EnvelopeGenerator ¶
type EnvelopeGenerator struct { Divider Divider `json:"divider"` Loop bool `json:"loop"` Disable bool `json:"disable"` Value byte `json:"value"` Counter byte `json:"counter"` }
func (*EnvelopeGenerator) Reset ¶
func (envelope *EnvelopeGenerator) Reset()
func (*EnvelopeGenerator) Set ¶
func (envelope *EnvelopeGenerator) Set(loop bool, disable bool, value byte)
func (*EnvelopeGenerator) Tick ¶
func (envelope *EnvelopeGenerator) Tick()
func (*EnvelopeGenerator) Volume ¶
func (envelope *EnvelopeGenerator) Volume() byte
type HostInput ¶
type HostInput interface {
Get() ButtonMapping
}
type Input ¶
type Instruction ¶
type Instruction struct { Name string Kind InstructionType Operands []byte }
func (*Instruction) Equals ¶
func (instruction *Instruction) Equals(other Instruction) bool
func (*Instruction) Length ¶
func (instruction *Instruction) Length() uint16
func (*Instruction) OperandByte ¶
func (instruction *Instruction) OperandByte() (byte, error)
func (*Instruction) OperandWord ¶
func (instruction *Instruction) OperandWord() (uint16, error)
func (*Instruction) String ¶
func (instruction *Instruction) String() string
type InstructionDescription ¶
type InstructionReader ¶
type InstructionReader struct {
// contains filtered or unexported fields
}
func NewInstructionReader ¶
func NewInstructionReader(data []byte) *InstructionReader
func (*InstructionReader) ReadInstruction ¶
func (reader *InstructionReader) ReadInstruction() (Instruction, error)
instructions can vary in their size
type InstructionTable ¶
type InstructionTable map[InstructionType]InstructionDescription
func MakeInstructionDescriptiontable ¶
func MakeInstructionDescriptiontable() InstructionTable
type InstructionType ¶
type InstructionType int
type LengthCounter ¶
func (*LengthCounter) Clear ¶
func (length *LengthCounter) Clear()
func (*LengthCounter) SetLength ¶
func (length *LengthCounter) SetLength(index byte)
func (*LengthCounter) Tick ¶
func (length *LengthCounter) Tick()
type Mapper ¶
type Mapper interface { // Write a value to the mapper address space Write(cpu *CPUState, address uint16, value byte) error // Read a value from the mapper address space Read(address uint16) byte // True if the irq line is asserted IsIRQAsserted() bool // Make a deep copy of this object Copy() Mapper // Return an int that identifies this type of mapper Kind() int // Return an error that describes any difference to another mapper, or nil if // there are no differences Compare(Mapper) error }
func MakeMapper ¶
func MakeMapper0 ¶
func MakeMapper1 ¶
func MakeMapper2 ¶
func MakeMapper3 ¶
func MakeMapper4 ¶
func MakeMapper7 ¶
func MakeMapper9 ¶
func MakeNSFMapper ¶
type Mapper0 ¶
type Mapper0 struct {
BankMemory []byte `json:"bank"`
}
func (*Mapper0) IsIRQAsserted ¶
type Mapper1 ¶
type Mapper1 struct { BankMemory []byte `json:"bankmemory"` CharacterMemory []byte `json:"charmemory"` Last4kBank int `json:"last4kbank"` /* how many bits to left shift the next value */ Shift int `json:"shift"` /* the value to pass to the mmc */ Register uint8 `json:"register"` Mirror byte `json:"mirror"` PrgBankMode byte `json:"prgbankmode"` ChrBankMode byte `json:"chrbankmode"` PrgBank byte `json:"prgbank"` /* FIXME: this might get mapped from the bank memory, not sure */ PRGRam []byte `json:"prgram"` }
http://wiki.nesdev.org/w/index.php/MMC1
func (*Mapper1) IsIRQAsserted ¶
type Mapper2 ¶
type Mapper2 struct { BankMemory []byte `json:"bankmemory"` SaveRam []byte `json:"saveram"` LastBankAddress uint32 `json:"lastaddress"` Bank byte `json:"bank"` }
func (*Mapper2) IsIRQAsserted ¶
type Mapper3 ¶
func (*Mapper3) IsIRQAsserted ¶
type Mapper4 ¶
type Mapper4 struct { ProgramRom []byte `json:"programrom"` CharacterRom []byte `json:"characterrom"` SaveRam []byte `json:"saveram"` LastBank int `json:"lastbank"` IrqEnabled bool `json:"irqenabled"` IrqReload byte `json:"irqreload"` IrqCounter byte `json:"irqcounter"` IrqPending bool `json:"irqpending"` WramEnabled bool `json:"wramenabled"` WramWrite bool `json:"wramwrite"` ChrMode byte `json:"chrmode"` PrgMode byte `json:"prgmode"` /* used to select which of the chrRegister/prgRegister to write to */ RegisterIndex byte `json:"register"` ChrRegister [6]byte `json:"chrregister"` PrgRegister [2]byte `json:"prgregister"` }
func (*Mapper4) CharacterBlock ¶
func (*Mapper4) IsIRQAsserted ¶
func (*Mapper4) SetChrBank ¶
type Mapper7 ¶
type Mapper7 struct { ProgramRom []byte `json:"programrom"` CharacterRom []byte `json:"characterrom"` Bank int `json:"bank"` // 0-7 Mirror int `json:"mirror"` // 0=1ScA, 1=1ScB }
func (*Mapper7) IsIRQAsserted ¶
type Mapper9 ¶
type Mapper9 struct { ProgramRom []byte `json:"programrom"` CharacterRom []byte `json:"characterrom"` Pages int `json:"pages"` PrgRegister byte `json:"prg"` ChrRegister [4]byte `json:"chr"` }
func (*Mapper9) CharacterBlock ¶
func (*Mapper9) IsIRQAsserted ¶
func (*Mapper9) SetChrBank ¶
type MapperState ¶
func (*MapperState) Compare ¶
func (state *MapperState) Compare(other MapperState) error
func (*MapperState) Copy ¶
func (state *MapperState) Copy() MapperState
func (*MapperState) Set ¶
func (state *MapperState) Set(mapper Mapper)
func (*MapperState) UnmarshalJSON ¶
func (state *MapperState) UnmarshalJSON(data []byte) error
type NESFile ¶
type NSFActions ¶
type NSFActions int
type NSFFile ¶
type NSFMapper ¶
func (*NSFMapper) IsIRQAsserted ¶
type NametableMirrorConfiguration ¶
type NametableMirrorConfiguration int
func (NametableMirrorConfiguration) String ¶
func (mirror NametableMirrorConfiguration) String() string
type NoInput ¶
type NoInput struct { }
func (*NoInput) Get ¶
func (buttons *NoInput) Get() ButtonMapping
type Noise ¶
type Noise struct { Length LengthCounter `json:"length"` Envelope EnvelopeGenerator `json:"envelope"` Mode byte `json:"mode"` Timer Timer `json:"timer"` ShiftRegister uint16 `json:"shift"` }
func (*Noise) GenerateSample ¶
type PPUState ¶
type PPUState struct { Flags byte `json:"flags"` Mask byte `json:"mask"` /* http://wiki.nesdev.org/w/index.php/PPU_registers#PPUSTATUS */ Status byte `json:"status"` /* counts in the y direction during rendering, from 0-262 */ Scanline int `json:"scanline"` /* counts in the x direction during rendering, from 0-340 */ ScanlineCycle int `json:"scanlinecycle"` TemporaryVideoAddress uint16 `json:"t_register"` /* the t register */ VideoAddress uint16 `json:"videoaddress"` /* the v register */ WriteState byte `json:"writestate"` /* for writing to the video address or the t register */ NametableMirror NametableMirrorConfiguration `json:"nametablemirror"` /* for scrolling */ FineX byte `json:"finex"` /* maps an nes integer 0-256 to an RGB value */ Palette [][]uint8 `json:"palette"` /* current sprites that will render on this scanline. a bit of a hack */ CurrentSprites []Sprite `json:"sprites"` VideoMemory []byte `json:"videomemory"` /* the 2kb SRAM stored on the NES board. * use nametable mirroring to map addresses to these ranges * Nametable[0:0x400] should appear at 0x2000 and 0x2800 in vertical mirroring * and 0x2000 and 0x2400 in horizontal mirroring. * Nametable[0x400:0x800] should appear at 0x2400 and 0x2c00 in vertical mirroring * and 0x2800 and 0x2c00 in horizontal mirroring. * * http://wiki.nesdev.org/w/index.php/PPU_nametables */ NametableMemory []byte `json:"nametablememory"` /* sprite memory */ OAM []byte `json:"oam"` OAMAddress int `json:"oamaddress"` /* makes the ppu print stuff via log.Printf if set to a value > 0 */ Debug uint8 `json:"-"` InternalVideoBuffer byte `json:"videobuffer"` /* how many times to shift out of the BackgroundPixels before needing to load a new tile */ Shifts byte `json:"shifts"` /* each pixel is 4 bits, each tile is 8 pixels * so first 32 bits is the first tile * and second 32 bits is the next tile. * As each pixel is rendered, the entire * thing is shifted 4 pixels to the right. * After 8 pixels are rendered, a new tile * is read from memory, its pixels computed, and * loaded into the upper 32 its of BackgroundPixels */ BackgroundPixels uint64 `json:"backgroundpixels"` RawBackgroundPixels uint32 `json:"rawbackgroundpixels"` /* not sure if this is needed */ HasSetSprite0 bool `json:"sprite0"` }
func (*PPUState) ConstructVideoAddress ¶
func (*PPUState) ControlString ¶
func (*PPUState) CopyCharacterRom ¶
func (*PPUState) DeconstructVideoAddress ¶
Returns fineY, nametable, coarseY, coarseX
func (*PPUState) GetBackgroundPatternTableBase ¶
func (*PPUState) GetNMIOutput ¶
func (*PPUState) GetNameTableBaseAddress ¶
func (*PPUState) GetNameTableIndex ¶
func (*PPUState) GetSpritePatternTableBase ¶
func (*PPUState) GetSpriteSize ¶
func (ppu *PPUState) GetSpriteSize() SpriteSize
func (*PPUState) GetSpriteZeroHit ¶
func (*PPUState) GetSprites ¶
func (*PPUState) GetVRamIncrement ¶
func (*PPUState) IncrementHorizontalAddress ¶
func (ppu *PPUState) IncrementHorizontalAddress()
func (*PPUState) IncrementVerticalPosition ¶
func (ppu *PPUState) IncrementVerticalPosition()
Bump the y scroll, wrapping the nametable if necessary
func (*PPUState) IsBackgroundEnabled ¶
func (*PPUState) IsSpriteEnabled ¶
func (*PPUState) IsVerticalBlankFlagSet ¶
func (*PPUState) LoadBackgroundTile ¶
func (ppu *PPUState) LoadBackgroundTile()
func (*PPUState) LoadNametableMemory ¶
func (*PPUState) MaskString ¶
func (*PPUState) PreloadTiles ¶
func (ppu *PPUState) PreloadTiles()
Load the first two tiles for the scanline
func (*PPUState) ReadStatus ¶
func (*PPUState) ReadVideoMemory ¶
func (*PPUState) RenderPixel ¶
func (ppu *PPUState) RenderPixel(scanLine int, cycle int, sprites []Sprite, screen *VirtualScreen) bool
Returns true for a sprite 0 hit
func (*PPUState) ResetHorizontalPosition ¶
func (ppu *PPUState) ResetHorizontalPosition()
func (*PPUState) SetControllerFlags ¶
func (*PPUState) SetHorizontalMirror ¶
func (ppu *PPUState) SetHorizontalMirror()
func (*PPUState) SetOAMAddress ¶
func (*PPUState) SetScreenAMirror ¶
func (ppu *PPUState) SetScreenAMirror()
func (*PPUState) SetScreenBMirror ¶
func (ppu *PPUState) SetScreenBMirror()
func (*PPUState) SetSpriteZeroHit ¶
func (*PPUState) SetVerticalBlankFlag ¶
func (*PPUState) SetVerticalMirror ¶
func (ppu *PPUState) SetVerticalMirror()
func (*PPUState) StoreNametableMemory ¶
func (*PPUState) ToggleDebug ¶
func (ppu *PPUState) ToggleDebug()
func (*PPUState) UpdateMapper4Scanline ¶
A bit of a hack, maybe make this more elegant later
func (*PPUState) WriteAddress ¶
func (*PPUState) WriteScroll ¶
func (*PPUState) WriteVideoMemory ¶
type Pulse ¶
type Pulse struct { Name string `json:"name"` Sweep Sweep `json:"sweep"` Timer Timer `json:"timer"` Envelope EnvelopeGenerator `json:"envelope"` Length LengthCounter `json:"length"` Frequency float32 `json:"frequency"` Phase float32 `json:"phase"` Duty byte `json:"duty"` Sequencer SquareSequencer `json:"sequencer"` }
func (*Pulse) GenerateSample ¶
func (*Pulse) ParseSweep ¶
type RecordInput ¶
type SpriteSize ¶
type SpriteSize int
type SquareSequencer ¶
func (*SquareSequencer) Run ¶
func (sequencer *SquareSequencer) Run(clocks int)
func (*SquareSequencer) SetDuty ¶
func (sequencer *SquareSequencer) SetDuty(duty byte)
func (*SquareSequencer) Value ¶
func (sequencer *SquareSequencer) Value() byte
type Sweep ¶
type Timer ¶
type Triangle ¶
type Triangle struct { Timer Timer `json:"timer"` Phase int `json:"phase"` Length LengthCounter `json:"length"` ControlFlag bool `json:"control"` LinearCounterReloadFlag bool `json:"linearcounterreloadflag"` LinearCounterReload int `json:"linearcounterreload"` LinearCounter int `json:"linearcounter"` }
func (*Triangle) GenerateSample ¶
func (*Triangle) TickLengthCounter ¶
func (triangle *Triangle) TickLengthCounter()
func (*Triangle) TickLinearCounter ¶
func (triangle *Triangle) TickLinearCounter()
type VirtualScreen ¶
func MakeVirtualScreen ¶
func MakeVirtualScreen(width int, height int) VirtualScreen
func (*VirtualScreen) Area ¶
func (screen *VirtualScreen) Area() int
func (*VirtualScreen) Clear ¶
func (screen *VirtualScreen) Clear()
func (*VirtualScreen) ClearToColor ¶
func (screen *VirtualScreen) ClearToColor(red uint8, green uint8, blue uint8)
func (*VirtualScreen) Copy ¶
func (screen *VirtualScreen) Copy() VirtualScreen
func (*VirtualScreen) CopyFrom ¶
func (screen *VirtualScreen) CopyFrom(copyFrom *VirtualScreen)