From afa7d0d3f6452884b26e46e19fc24078065525dd Mon Sep 17 00:00:00 2001 From: Ariejan de Vroom Date: Tue, 12 Aug 2014 20:46:41 +0200 Subject: [PATCH] Wip --- bus/bus.go | 10 +++++--- cpu/cpu.go | 62 +++++++++++++++++++++++++++++++++++---------- cpu/instruction.go | 17 ++++++++++++- devices/via6522.go | 21 +++++++++++++++ intcore | Bin 0 -> 32768 bytes machine.go | 20 ++++++++++++--- rom/ehbasic.rom | Bin 16384 -> 16384 bytes 7 files changed, 109 insertions(+), 21 deletions(-) create mode 100644 devices/via6522.go create mode 100644 intcore diff --git a/bus/bus.go b/bus/bus.go index bd6e4a7..64c4885 100644 --- a/bus/bus.go +++ b/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) diff --git a/cpu/cpu.go b/cpu/cpu.go index 682592d..f810593 100644 --- a/cpu/cpu.go +++ b/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. diff --git a/cpu/instruction.go b/cpu/instruction.go index 7d85095..5088a10 100644 --- a/cpu/instruction.go +++ b/cpu/instruction.go @@ -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} diff --git a/devices/via6522.go b/devices/via6522.go new file mode 100644 index 0000000..3b4b20d --- /dev/null +++ b/devices/via6522.go @@ -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 +} diff --git a/intcore b/intcore new file mode 100644 index 0000000000000000000000000000000000000000..d993fb101b996f7acce2ba58850c2cf186e4bf06 GIT binary patch literal 32768 zcmeIuJxT*X6ae7CkVbINAnDx7&c#B~8R8y71Ys|dqXaAz(%1*Ia4S<)G1>qC literal 0 HcmV?d00001 diff --git a/machine.go b/machine.go index 0b6a4bb..2931378 100644 --- a/machine.go +++ b/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 diff --git a/rom/ehbasic.rom b/rom/ehbasic.rom index e88c0c96d141e52133217d6150056e9a8d390bb0..3e58e06342718d6fbf919b2bc17e1324ef7f8897 100644 GIT binary patch delta 41 wcmZo@U~Fh$+|X|?q@&V!+%~T03_lJ;s5{u