mirror of
https://github.com/ariejan/i6502.git
synced 2025-03-15 03:29:42 +00:00
Wip
This commit is contained in:
parent
9e3c9454e8
commit
afa7d0d3f6
10
bus/bus.go
10
bus/bus.go
@ -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)
|
||||
|
62
cpu/cpu.go
62
cpu/cpu.go
@ -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.
|
||||
|
@ -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
21
devices/via6522.go
Normal 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
|
||||
}
|
20
machine.go
20
machine.go
@ -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
|
||||
|
BIN
rom/ehbasic.rom
BIN
rom/ehbasic.rom
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user