internal/{cpu,vm}: add memory to the vm, and refactor cpu/vm/memory code

This commit is contained in:
Bradford Lamson-Scribner 2020-05-27 21:19:43 -06:00
parent 17df9a44f0
commit f77b94f885
5 changed files with 66 additions and 38 deletions

View File

@ -4,4 +4,5 @@ Current references:
- [6502 instruction set](https://www.masswerk.at/6502/6502_instruction_set.html)
- [6502 memory test](http://www.willegal.net/appleii/6502mem.htm)
- [6502 instructions description with undocumented commands](http://www.zimmers.net/anonftp/pub/cbm/documents/chipdata/64doc)
- [a rust implementation](https://github.com/alexander-akhmetov/mos6502)
- [a rust implementation](https://github.com/alexander-akhmetov/mos6502)
- [MOS hardware manual](http://bytecollector.com/archive/misc/6500-10A_MCS6500hwMan_Jan76.pdf)

View File

@ -1,5 +1,5 @@
package cpu
// Package cpu emulates a Mos6502 cpu
//
// A .... Accumulator OPC A operand is AC (implied single byte instruction)
// abs .... absolute OPC $LLHH operand is address $HHLL *
// abs,X .... absolute, X-indexed OPC $LLHH,X operand is address; effective address is address incremented by X with carry **
@ -13,9 +13,9 @@ package cpu
// zpg .... zeropage OPC $LL operand is zeropage address (hi-byte is zero, address = $00LL)
// zpg,X .... zeropage, X-indexed OPC $LL,X operand is zeropage address; effective address is address incremented by X without carry **
// zpg,Y .... zeropage, Y-indexed OPC $LL,Y operand is zeropage address; effective address is address incremented by Y without carry **
//
// 16-bit address words are little endian, lo(w)-byte first, followed by the hi(gh)-byte.
//
// SR Flags (bit 7 to bit 0):
// N .... Negative
// V .... Overflow
@ -25,15 +25,16 @@ package cpu
// I .... Interrupt (IRQ disable)
// Z .... Zero
// C .... Carry
//
// Processor Stack:
// LIFO, top down, 8 bit range, 0x0100 - 0x01FF
package cpu
// addressingMode is a type alias for a string, used below for defining addressing mode types
type addressingMode int
// addrMode is a type alias for a string, used below for defining addressing modes
type addrMode int
const (
accumulator addressingMode = iota
accumulator addrMode = iota
absolute
absoluteXIndexed
absoluteYIndexed
@ -48,17 +49,39 @@ const (
zeroPageYIndexed
)
// Available cpu flags written as binary integer literals
const (
flagDefault uint8 = 0B_00110000
flagNegative uint8 = 0B_10000000
flagOverflow uint8 = 0B_01000000
flagB uint8 = 0B_00010000
flagDecimal uint8 = 0B_00001000
flagInterrupt uint8 = 0B_00000100
flagZero uint8 = 0B_00000010
flagCarry uint8 = 0B_00000001
)
// StackBottom represents the bottom address
const StackBottom uint16 = 0x0100 // 256
// Mos6502 TODO: docs
type Mos6502 struct {
pc uint16 // program counter (16 bit)
ac uint8 // accumulator (8 bit)
x uint8 // X register (8 bit)
y uint8 // Y register (8 bit)
sr uint8 // status register [NV-BDIZC] (8 bit)
sp uint8 // stack pointer (8 bit)
sp uint8 // stack pointer
pc uint16 // program counter
a uint8 // accumulator register
x uint8 // X index register
y uint8 // Y index register
p uint8 // processor flags
}
// New TODO: docs
func New() *Mos6502 {
return &Mos6502{}
return &Mos6502{
sp: 0xFF,
pc: 0,
a: 0,
x: 0,
y: 0,
p: flagDefault,
}
}

View File

@ -3,18 +3,18 @@ package cpu
// op represents an operation. It includes the name of the op, it's 8 bit hexidecimal
// opcode, how many bytes it occupies (it's size), as well as it's addressing mode.
type op struct {
name string
opcode uint8
size uint8
addressingMode addressingMode
name string
opcode uint8
size uint8
addrMode addrMode
}
func newOp(name string, opcode, size uint8, addressingMode addressingMode) op {
func newOp(name string, opcode, size uint8, addrMode addrMode) op {
return op{
name: name,
opcode: opcode,
size: size,
addressingMode: addressingMode,
name: name,
opcode: opcode,
size: size,
addrMode: addrMode,
}
}

17
internal/vm/vm.go Normal file
View File

@ -0,0 +1,17 @@
package vm
import "github.com/bradford-hamilton/apple-1/internal/cpu"
// Appleone represents the virtual Apple 1 computer
type Appleone struct {
cpu *cpu.Mos6502 // virtual Mos6502 cpu
mem [64 * 1024]byte // available memory (64kiB)
}
// New returns a pointer to an initialized Appleone with a brand spankin new CPU
func New() *Appleone {
return &Appleone{
cpu: cpu.New(),
mem: [64 * 1024]byte{},
}
}

View File

@ -1,13 +0,0 @@
package appleone
import "github.com/bradford-hamilton/apple-1/internal/cpu"
// Appleone represents our virtual Apple 1 computer
type Appleone struct {
cpu *cpu.Mos6502
}
// New returns a pointer to an initialized Appleone with a brand spankin new CPU
func New() *Appleone {
return &Appleone{cpu: cpu.New()}
}