Skip to content

Commit

Permalink
Need to figure out what's killing performance.
Browse files Browse the repository at this point in the history
  • Loading branch information
ExpandingMan committed May 16, 2017
1 parent 3c45ea3 commit 50527c3
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 33 deletions.
11 changes: 10 additions & 1 deletion src/boilerplate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ end
function opdef_Absolute(opname::Symbol, opcode::UInt8)
fname = opfuncname(opcode)
quote
$fname(cs::Chipset, bytes::AbstractVector{UInt8}) = $opname(cs.cpu, cs.ram, Π16(bytes))
$fname(cs::Chipset, bytes::AbstractVector{UInt8}) = $opname(cs.cpu, cs.ram, Direct, Π16(bytes))
end
end

Expand All @@ -66,6 +66,13 @@ function opdef_AbsoluteY(opname::Symbol, opcode::UInt8)
end
end

function opdef_Indirect(opname::Symbol, opcode::UInt8)
fname = opfuncname(opcode)
quote
$fname(cs::Chipset, bytes::AbstractVector{UInt8}) = $opname(cs.cpu, cs.ram, Indirect, Π16(bytes))
end
end

function opdef_IndirectX(opname::Symbol, opcode::UInt8)
fname = opfuncname(opcode)
quote
Expand Down Expand Up @@ -102,6 +109,8 @@ function opdef(mode::Symbol, opname::Symbol, opcode::UInt8)
return opdef_AbsoluteX(opname, opcode)
elseif mode == :AbsoluteY
return opdef_AbsoluteY(opname, opcode)
elseif mode == :Indirect
return opdef_Indirect(opname, opcode)
elseif mode == :IndirectX
return opdef_IndirectX(opname, opcode)
elseif mode == :IndirectY
Expand Down
1 change: 1 addition & 0 deletions src/chipset.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ for this thing as generic as possible!


# this will serve as the default. Note this was the NES mater clock / 16
# this works out to about 559ns
const NES_CLOCK_PERIOD = 1.0/1.662607 * 10.0^(-6)


Expand Down
147 changes: 131 additions & 16 deletions src/opcodes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,22 @@ deref_opargs(cs::Chipset, ptr::Π, nbytes::Integer) = deref(ptr+0x01, cs.ram, nb
===================================================================================================#
# this doesn't do the sleeping
function tick!(cs::Chipset)
nbytes, ncycles = op!(cs, Π(cs.cpu.PC))
exe, nbytes, ncycles = op!(cs, Π(cs.cpu.PC))
cs.cpu.PC += nbytes
cs.clock += ncycles
nbytes, ncycles
exe(), nbytes, ncycles
end


# op! doesn't increment clock or instruction pointer
function op!(cs::Chipset, bytes::AbstractVector{UInt8})
@inline function op!(cs::Chipset, bytes::AbstractVector{UInt8})
exe!, nbytes, ncycles = OPCODES[bytes[1]]
exe!(cs, bytes[2:end])
nbytes, ncycles
() -> exe!(cs, bytes[2:end]), nbytes, ncycles
end

function op!(cs::Chipset, ptr:)
@inline function op!(cs::Chipset, ptr:)
exe!, nbytes, ncycles = OPCODES[deref(ptr, cs.ram)]
exe!(cs, deref_opargs(cs, ptr, nbytes))
nbytes, ncycles
() -> exe!(cs, deref_opargs(cs, ptr, nbytes)), nbytes, ncycles
end


Expand All @@ -52,16 +50,21 @@ export op!, tick!
# returns func, nbytes, ncycles
const OPCODES = Dict{UInt8,Tuple{Function,Int,Int}}(); sizehint!(OPCODES, N_OPCODES)

# format is
# mode, opcode, nbytes, ncycles

# we treat "Accumulator" mode as "Implicit"


@opdef lda! begin
Immediate, 0x69, 2, 2
ZeroPage, 0x65, 2, 3
ZeroPageX, 0x75, 2, 4
Absolute, 0x6d, 3, 4
AbsoluteX, 0x7d, 3, 4 # TODO should automatically take care of page crossings
AbsoluteY, 0x79, 3, 4
IndirectX, 0x61, 2, 6
IndirectY, 0x71, 2, 5
Immediate, 0xa9, 2, 2
ZeroPage, 0xa5, 2, 3
ZeroPageX, 0xb5, 2, 4
Absolute, 0xad, 3, 4
AbsoluteX, 0xbd, 3, 4 # TODO should automatically take care of page crossings
AbsoluteY, 0xb9, 3, 4
IndirectX, 0xa1, 2, 6
IndirectY, 0xb1, 2, 5
end

@opdef ldx! begin
Expand Down Expand Up @@ -180,6 +183,118 @@ end
Absolute, 0x2c, 3, 4
end

@opdef adc! begin
Immediate, 0x69, 2, 2
ZeroPage, 0x65, 2, 3
ZeroPageX, 0x75, 2, 4
Absolute, 0x6d, 3, 4
AbsoluteX, 0x7d, 3, 4
AbsoluteY, 0x79, 3, 4
IndirectX, 0x61, 2, 6
IndirectY, 0x71, 2, 5
end

@opdef sbc! begin
Immediate, 0xe9, 2, 2
ZeroPage, 0xe5, 2, 3
ZeroPageX, 0xf5, 2, 4
Absolute, 0xed, 3, 4
AbsoluteX, 0xfd, 3, 4
AbsoluteY, 0xf9, 3, 4
IndirectX, 0xe1, 2, 6
IndirectY, 0xf1, 2, 5
end

@opdef cmp! begin
Immediate, 0xc9, 2, 2
ZeroPage, 0xc5, 2, 3
ZeroPageX, 0xd5, 2, 4
Absolute, 0xcd, 3, 4
AbsoluteX, 0xdd, 3, 4
AbsoluteY, 0xd9, 3, 4
IndirectX, 0xc1, 2, 6
IndirectY, 0xd1, 2, 5
end

@opdef cpx! begin
Immediate, 0xe0, 2, 2
ZeroPage, 0xe4, 2, 3
Absolute, 0xec, 3, 4
end

@opdef cpy! begin
Immediate, 0xc0, 2, 2
ZeroPage, 0xc4, 2, 3
Absolute, 0xcc, 3, 4
end

@opdef inc! begin
ZeroPage, 0xe6, 2, 5
ZeroPageX, 0xf6, 2, 6
Absolute, 0xee, 3, 6
AbsoluteX, 0xfe, 3, 7
end

@opdef inx! begin
Implicit, 0xe8, 1, 2
end

@opdef iny! begin
Implicit, 0xc8, 1, 2
end

@opdef dec! begin
ZeroPage, 0xc6, 2, 5
ZeroPageX, 0xd6, 2, 6
Absolute, 0xce, 3, 6
AbsoluteX, 0xde, 3, 7
end

@opdef dex! begin
Implicit, 0xca, 1, 2
end

@opdef dey! begin
Implicit, 0x88, 1, 2
end

@opdef asl! begin
Implicit, 0x0a, 1, 2
ZeroPage, 0x06, 2, 5
ZeroPageX, 0x16, 2, 6
Absolute, 0x0e, 3, 6
AbsoluteX, 0x1e, 3, 7
end

@opdef lsr! begin
Implicit, 0x4a, 1, 2
ZeroPage, 0x46, 2, 5
ZeroPageX, 0x56, 2, 6
Absolute, 0x4e, 3, 6
AbsoluteX, 0x5e, 3, 7
end

@opdef rol! begin
Implicit, 0x2a, 1, 2
ZeroPage, 0x26, 2, 5
ZeroPageX, 0x36, 2, 6
Absolute, 0x2e, 3, 6
AbsoluteX, 0x3e, 3, 7
end

@opdef ror! begin
Implicit, 0x6a, 1, 2
ZeroPage, 0x66, 2, 5
ZeroPageX, 0x76, 2, 6
Absolute, 0x6e, 3, 6
AbsoluteX, 0x7e, 3, 7
end

# TODO haven't decided how to do this yet!
@opdef jmp! begin
Immediate, 0x4c, 3, 3
Absolute, 0x6c, 3, 5
end
#===================================================================================================
</opcodes>
===================================================================================================#
52 changes: 36 additions & 16 deletions test/opcodes.jl
Original file line number Diff line number Diff line change
@@ -1,30 +1,50 @@
using Sim6502
using BenchmarkTools

cs = Chipset()

macro program(vec)
esc(quote
cs.ram[0x0600:(0x0600+length($vec)-1)] = $vec
end)
end

macro p(expr)
esc(:($expr; println(cs.cpu)))
end

macro program(vec)
esc(quote
cs.ram[0x0600:(0x0600+length($vec)-1)] = $vec
end)

function makechipset()
cs = Chipset()

cs.ram[0x00] = 0x01
cs.ram[0x01] = 0x02

cs.ram[0xa000] = 0x05
cs.ram[0xa001] = 0x06

# @p Sim6502.op0xa5!(cs, [0x00])
# @p Sim6502.op0xad!(cs, [0x01, 0xa0])
# @p Sim6502.op0xaa!(cs, UInt8[])
@program [0xa5, 0x00, 0xad, 0x01, 0xa0, 0xaa, 0xaa, 0xaa]

cs
end

cs.ram[0x00] = 0x01
cs.ram[0x01] = 0x02

cs.ram[0xa000] = 0x05
cs.ram[0xa001] = 0x06
b = @benchmarkable begin
# tick!(cs)
# tick!(cs)
# tick!(cs)

# cs.cpu.A = 0x00
# Sim6502.checkNflag!(cs.cpu, cs.cpu.A)
# Sim6502.checkZflag!(cs.cpu, cs.cpu.A)
# cs.cpu.A = cs.ram[0xa001]
# cs.cpu.X = cs.cpu.A

# @p Sim6502.op0x65!(cs, [0x00])
# @p Sim6502.op0x6d!(cs, [0x01, 0xa0])
# @p Sim6502.op0xaa!(cs, UInt8[])
@program [0x65, 0x00, 0x6d, 0x01, 0xa0, 0xaa]
lda!(cs.cpu, 0x00)
lda!(cs.cpu, cs.ram, Π(0xa001))
tax!(cs.cpu)
end setup=(cs = makechipset())

@p tick!(cs)
@p tick!(cs)
@p tick!(cs)

0 comments on commit 50527c3

Please sign in to comment.