This commit is contained in:
Ariejan de Vroom 2014-08-12 20:46:41 +02:00
parent 9e3c9454e8
commit afa7d0d3f6
7 changed files with 109 additions and 21 deletions

View File

@ -58,7 +58,7 @@ func (bus *Bus) backendFor(address uint16) (memory.Memory, error) {
}
}
return nil, fmt.Errorf("No module addressable at 0x%04X", address)
return nil, fmt.Errorf("No module addressable at 0x%04X\n", address)
}
// Read an 8-bit value from the module mapped on the bus at the
@ -66,7 +66,9 @@ func (bus *Bus) backendFor(address uint16) (memory.Memory, error) {
func (bus *Bus) Read(address uint16) byte {
memory, err := bus.backendFor(address)
if err != nil {
panic(err)
fmt.Printf("Reading from invalid address $%04X. Returning $00\n", address)
return 0x00
// panic(err)
}
value := memory.Read(address)
@ -78,7 +80,9 @@ func (bus *Bus) Read(address uint16) byte {
func (bus *Bus) Write(address uint16, value byte) {
memory, err := bus.backendFor(address)
if err != nil {
panic(err)
fmt.Printf("Writing to invalid address $%04X. Faking write.\n", address)
return
// panic(err)
}
memory.Write(address, value)

View File

@ -20,7 +20,12 @@ const (
// Beginning of the stack.
// The stack grows downward, so it starts at 0x1FF
const StackBase = 0x0100
const (
StackBase = 0x0100
NmiVector = 0xFFFA // + 0xFFFB
ResetVector = 0xFFFC // + 0xFFFD
IrqVector = 0xFFFE // + 0xFFFF
)
type Cpu struct {
// Program counter
@ -42,7 +47,8 @@ type Cpu struct {
// Memory bus
Bus *bus.Bus
InterruptChan chan bool
IrqChan chan bool
NmiChan chan bool
// Handle exiting
ExitChan chan int
@ -53,7 +59,7 @@ type Cpu struct {
// address 0xFFFC into the Program Counter. Note this is a 16 bit value, read from
// 0xFFFC-FFFD
func (c *Cpu) Reset() {
c.PC = c.Bus.Read16(0xFFFC)
c.PC = c.Bus.Read16(ResetVector)
c.SR = 0x34
}
@ -65,7 +71,15 @@ func (c *Cpu) String() string {
)
}
func (c *Cpu) handleInterrupt(returnPC uint16) {
func (c *Cpu) handleIrq(returnPC uint16) {
c.handleInterrupt(returnPC, IrqVector)
}
func (c *Cpu) handleNmi() {
c.handleInterrupt(c.PC, NmiVector)
}
func (c *Cpu) handleInterrupt(returnPC uint16, vector uint16) {
c.setStatus(sBreak, true)
// Push PC + 1 onto stack
@ -77,7 +91,7 @@ func (c *Cpu) handleInterrupt(returnPC uint16) {
// Disable interrupts
c.setStatus(sInterrupt, true)
c.PC = c.Bus.Read16(0xFFFE)
c.PC = c.Bus.Read16(vector)
}
func (c *Cpu) stackPush(data byte) {
@ -92,11 +106,13 @@ func (c *Cpu) stackPop() byte {
func (c *Cpu) Step() {
select {
case <-c.InterruptChan:
case <-c.IrqChan:
if !c.getStatus(sInterrupt) {
// Handle interrupt
c.handleInterrupt(c.PC)
c.handleIrq(c.PC)
}
case <-c.NmiChan:
c.handleNmi()
default:
// Read the instruction (including operands)
instruction := ReadInstruction(c.PC, c.Bus)
@ -105,13 +121,19 @@ func (c *Cpu) Step() {
// on the size of the optype we just read.
c.PC += uint16(instruction.Bytes)
fmt.Printf(instruction.String())
// Execute the instruction
c.execute(instruction)
}
}
func (c *Cpu) stackHead(offset int8) uint16 {
return uint16(StackBase) + uint16(c.SP) + uint16(offset)
address := uint16(StackBase) + uint16(c.SP) + uint16(offset)
val8 := c.Bus.Read(address)
val16 := c.Bus.Read16(address)
fmt.Printf("Addressing Stack at 0x%04X (8: 0x%02X; 16: 0x%04X from PC 0x%04X\n", address, val8, val16, c.PC)
return address
}
func (c *Cpu) resolveOperand(in Instruction) uint8 {
@ -285,6 +307,8 @@ func (c *Cpu) execute(in Instruction) {
c.ROL(in)
case ror:
c.ROR(in)
case rti:
c.RTI(in)
case rts:
c.RTS(in)
case sbc:
@ -393,10 +417,13 @@ func (c *Cpu) BPL(in Instruction) {
// BRK: software interrupt
func (c *Cpu) BRK(in Instruction) {
fmt.Println("BRK:", c)
c.ExitChan <- 42
// Force interrupt
if !c.getStatus(sInterrupt) {
c.handleInterrupt(c.PC + 1)
}
// if !c.getStatus(sInterrupt) {
// c.handleIrq(c.PC + 1)
// }
}
// CLC: Clear carry flag.
@ -595,11 +622,18 @@ func (c *Cpu) ROR(in Instruction) {
}
}
// RTS: Return from subroutine.
func (c *Cpu) RTS(in Instruction) {
// RTI: Return from interrupt
func (c *Cpu) RTI(in Instruction) {
c.SR = c.stackPop()
c.PC = c.Bus.Read16(c.stackHead(1))
c.SP += 2
c.PC += 1
fmt.Printf("RTI: Returning to 0x%04X", c.PC)
}
// RTS: Return from subroutine.
func (c *Cpu) RTS(in Instruction) {
c.PC = c.Bus.Read16(c.stackHead(1)) + 1
c.SP += 2
}
// SBC: Subtract memory with borrow from accumulator.

View File

@ -17,6 +17,21 @@ type Instruction struct {
Op16 uint16
}
func (i *Instruction) String() string {
var output string
switch i.Bytes {
case 1:
output = fmt.Sprintf("0x%02X - %s\n", i.Opcode, instructionNames[i.id])
case 2:
output = fmt.Sprintf("0x%02X - %s %02X\n", i.Opcode, instructionNames[i.id], i.Op8)
case 3:
output = fmt.Sprintf("0x%02X - %s %04X\n", i.Opcode, instructionNames[i.id], i.Op16)
}
return output
}
func ReadInstruction(pc uint16, bus *bus.Bus) Instruction {
// Read the opcode
opcode := bus.Read(pc)
@ -24,7 +39,7 @@ func ReadInstruction(pc uint16, bus *bus.Bus) Instruction {
// Do we know this opcode in our optypes table?
optype, ok := optypes[opcode]
if !ok {
panic(fmt.Sprintf("Unknown opcode $%02X at $04X", opcode, pc))
panic(fmt.Sprintf("Unknown opcode $%02X at $%04X", opcode, pc))
}
instruction := Instruction{OpType: optype}

21
devices/via6522.go Normal file
View File

@ -0,0 +1,21 @@
package devices
type Via6522 struct {
}
func (v *Via6522) Size() int {
return 0x10
}
func (v *Via6522) Read(address uint16) byte {
return 0x00
}
func (v *Via6522) Write(address uint16, data byte) {
// NOP
}
func NewVia6522(interruptChan chan bool) *Via6522 {
via := &Via6522{}
return via
}

BIN
intcore Normal file

Binary file not shown.

View File

@ -5,6 +5,7 @@ import (
"github.com/ariejan/i6502/cpu"
"github.com/ariejan/i6502/devices"
"github.com/ariejan/i6502/memory"
"os"
)
type Machine struct {
@ -22,7 +23,8 @@ type Machine struct {
// Creates a new i6502 Machine instance
func CreateMachine() *Machine {
// Channel for handling interrupts
interruptChan := make(chan bool, 0)
irqChan := make(chan bool, 0)
nmiChan := make(chan bool, 0)
ram := memory.CreateRam()
@ -31,14 +33,16 @@ func CreateMachine() *Machine {
panic(err)
}
acia6551 := devices.NewAcia6551(interruptChan)
acia6551 := devices.NewAcia6551(irqChan)
via6522 := devices.NewVia6522(irqChan)
bus, _ := bus.CreateBus()
bus.Attach(ram, "32kB RAM", 0x0000)
bus.Attach(rom, "16kB ROM", 0xC000)
bus.Attach(via6522, "VIA 6522 Parallel", 0x8000)
bus.Attach(acia6551, "ACIA 6551 Serial", 0x8800)
cpu := &cpu.Cpu{Bus: bus, InterruptChan: interruptChan, ExitChan: make(chan int, 0)}
cpu := &cpu.Cpu{Bus: bus, IrqChan: irqChan, NmiChan: nmiChan, ExitChan: make(chan int, 0)}
machine := &Machine{SerialTx: make(chan byte, 256), SerialRx: make(chan byte, 256), cpu: cpu, bus: bus}
@ -69,6 +73,16 @@ func CreateMachine() *Machine {
}
}()
go func() {
for {
select {
case <-machine.cpu.ExitChan:
ram.Dump("intcore")
os.Exit(42)
}
}
}()
cpu.Reset()
return machine

Binary file not shown.