2014-08-12 19:28:30 +00:00
|
|
|
package i6502
|
|
|
|
|
2014-08-13 11:51:53 +00:00
|
|
|
import "fmt"
|
|
|
|
|
2014-08-12 19:28:30 +00:00
|
|
|
type Cpu struct {
|
2014-08-13 07:26:33 +00:00
|
|
|
bus *AddressBus // The address bus
|
|
|
|
|
|
|
|
PC uint16 // 16-bit program counter
|
|
|
|
P byte // Status Register
|
|
|
|
}
|
|
|
|
|
|
|
|
const (
|
2014-08-13 09:49:49 +00:00
|
|
|
ResetVector = 0xFFFC // 0xFFFC-FFFD
|
2014-08-13 07:26:33 +00:00
|
|
|
)
|
|
|
|
|
2014-08-13 09:49:49 +00:00
|
|
|
// Create an new Cpu instance with the specified AddressBus
|
2014-08-13 07:26:33 +00:00
|
|
|
func NewCpu(bus *AddressBus) (*Cpu, error) {
|
|
|
|
return &Cpu{bus: bus}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Cpu) HasAddressBus() bool {
|
|
|
|
return c.bus != nil
|
2014-08-12 19:28:30 +00:00
|
|
|
}
|
|
|
|
|
2014-08-13 09:49:49 +00:00
|
|
|
// Reset the CPU, emulating the RESB pin.
|
2014-08-13 07:26:33 +00:00
|
|
|
func (c *Cpu) Reset() {
|
|
|
|
c.PC = c.bus.Read16(ResetVector)
|
|
|
|
c.P = 0x34
|
2014-08-12 19:28:30 +00:00
|
|
|
}
|
2014-08-13 09:49:49 +00:00
|
|
|
|
|
|
|
// Load the specified program data at the given memory location
|
|
|
|
// and point the Program Counter to the beginning of the program
|
|
|
|
func (c *Cpu) LoadProgram(data []byte, location uint16) {
|
|
|
|
for i, b := range data {
|
|
|
|
c.bus.Write(location+uint16(i), b)
|
|
|
|
}
|
|
|
|
|
|
|
|
c.PC = location
|
|
|
|
}
|
2014-08-13 11:51:53 +00:00
|
|
|
|
|
|
|
// Execute the instruction pointed to by the Program Counter (PC)
|
|
|
|
func (c *Cpu) Step() {
|
|
|
|
instruction := c.readNextInstruction()
|
|
|
|
c.PC += uint16(instruction.Size)
|
|
|
|
fmt.Println(instruction)
|
|
|
|
c.execute(instruction)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Cpu) execute(instruction Instruction) {
|
|
|
|
}
|