From 5d4506693ec2f3ef7a1ab9aa46bc10a3cd1e818d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Friis=20=C3=98stergaard?= Date: Sat, 31 Dec 2022 09:18:33 +0100 Subject: [PATCH 1/3] Try running the new suite, and fix a couple of instructions --- lib/mos6510/cpu.rb | 14 ++++++++++++++ lib/mos6510/jssid_mos6510.rb | 30 ++++++++++++++++-------------- spec/cpu_spec.rb | 6 +++--- 3 files changed, 33 insertions(+), 17 deletions(-) diff --git a/lib/mos6510/cpu.rb b/lib/mos6510/cpu.rb index 60e3a11..ead9c23 100644 --- a/lib/mos6510/cpu.rb +++ b/lib/mos6510/cpu.rb @@ -31,6 +31,20 @@ def pc=(new_pc) @cpu.pc = new_pc end + def inspect + status = @cpu.p + status_encoded = [ + (status & Mos6510::Flag::N) != 0, (status & Mos6510::Flag::V) != 0, (status & Mos6510::Flag::B2) != 0, (status & Mos6510::Flag::B1) != 0, (status & Mos6510::Flag::D) != 0, + (status & Mos6510::Flag::I) != 0, (status & Mos6510::Flag::Z) != 0, (status & Mos6510::Flag::C) != 0 + ].reduce(0) { |acc, flag| (acc << 1) + (flag ? 1 : 0) } + + format( + 'a: 0x%02x, x: 0x%02x, y: 0x%02x, sp: 0x%02x, ' \ + 'pc: 0x%04x, op: 0x%02x, status: 0b%08b, memory: %i', + @cpu.a, @cpu.x, @cpu.y, @cpu.s, @cpu.pc, @cpu.getmem(@cpu.pc), status_encoded, @memory.sum + ) + end + def peek(address) @cpu.getmem(address) end diff --git a/lib/mos6510/jssid_mos6510.rb b/lib/mos6510/jssid_mos6510.rb index 6bdd4d2..446a7da 100644 --- a/lib/mos6510/jssid_mos6510.rb +++ b/lib/mos6510/jssid_mos6510.rb @@ -275,7 +275,7 @@ def reset self.a = 0 self.x = 0 self.y = 0 - self.p = 0 + self.p = Flag::B1 | Flag::B2 self.s = 255 self.pc = self.getmem(0xfffc) self.pc |= 256 * self.getmem(0xfffd) @@ -291,12 +291,16 @@ def step case cmd when Inst::ADC - self.wval = self.a + self.getaddr(addr) + ((self.p & Flag::C) != 0 ? 1 : 0) + value = self.getaddr(addr) + carry = (self.p & Flag::C) != 0 ? 1 : 0 + self.wval = self.a + value + ((self.p & Flag::C) != 0 ? 1 : 0) + v = (((self.a & 0x7f) + (value & 0x7f) + carry) >> 7) ^ (self.wval >> 8) self.setflags(Flag::C, self.wval & 0x100) self.a = self.wval & 0xff self.setflags(Flag::Z, self.a == 0) self.setflags(Flag::N, self.a & 0x80) - self.setflags(Flag::V, ((self.p & Flag::C) != 0 ? 1 : 0) ^ ((self.p & Flag::N) != 0 ? 1 : 0)) + #puts "ADC setting v: #{v} (value=#{value}, carry=#{carry}, a=#{self.a}, wval=#{self.wval})" + self.setflags(Flag::V, v) when Inst::AND self.bval = self.getaddr(addr) self.a &= self.bval @@ -331,14 +335,12 @@ def step self.setflags(Flag::N, self.bval & 0x80) self.setflags(Flag::V, self.bval & 0x40) when Inst::BRK - pc = 0 # just quit per rockbox - #self.push(self.pc & 0xff); - #self.push(self.pc >> 8); - #self.push(self.p); - #self.setflags(jsSID.MOS6510.Flag::B, 1); - # FIXME: should Z be set as well? - #self.pc = self.getmem(0xfffe); - #self.cycles += 7; + self.push(self.pc >> 8) + self.push(self.pc & 0xff) + self.push(self.p) + self.setflags(Flag::B1, 1) + self.pc = self.getmem(0xfffe) + self.cycles += 7 when Inst::CLC self.cycles += 2 self.setflags(Flag::C, 0) @@ -491,7 +493,7 @@ def step self.setflags(Flag::N, self.a & 0x80) self.cycles += 4 when Inst::PLP - self.p = self.pop + self.p = self.pop | Flag::B1 | Flag::B2 self.cycles += 4 when Inst::ROL self.bval = self.getaddr(addr) @@ -583,7 +585,7 @@ def jsr(npc, na) self.a = na self.x = 0 self.y = 0 - self.p = 0 + self.p = Flag::B1 | Flag::B2 self.s = 255 self.pc = npc self.push(0) @@ -598,7 +600,7 @@ def jsr(npc, na) # Flags Enum module Flag - N = 128; V = 64; B = 16; D = 8; I = 4; Z = 2; C = 1 + N = 128; V = 64; B2 = 32; B1 = 16; D = 8; I = 4; Z = 2; C = 1 end # Opcodes Enum diff --git a/spec/cpu_spec.rb b/spec/cpu_spec.rb index dfb745c..5afe04b 100644 --- a/spec/cpu_spec.rb +++ b/spec/cpu_spec.rb @@ -16,7 +16,7 @@ module Mos6510 expect(cpu.peek(4000)).to eq(7) end - it "can run the whole Klaus Dormann functional test suite", skip: "Needs more work!" do + it "can run the whole Klaus Dormann functional test suite" do#, skip: "Needs more work!" do # TODO: This suite does _not_ pass currently. It relies on you copying # bin_files/6502_functional_test.bin from https://github.com/Klaus2m5/6502_65C02_functional_tests # (and even then, it ends up on the wrong PC) @@ -29,9 +29,9 @@ module Mos6510 last_pc = 0 while last_pc != cpu.pc last_pc = cpu.pc - #puts cpu.inspect + puts cpu.inspect - puts "Stepping: #{last_pc}" + #puts "Stepping: #{last_pc}" cpu.step end From 0d40a588b7940713ab85a54f9d7237a1afe72441 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Friis=20=C3=98stergaard?= Date: Sun, 1 Jan 2023 12:07:39 +0100 Subject: [PATCH 2/3] Getting further and further... --- lib/mos6510/jssid_mos6510.rb | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/lib/mos6510/jssid_mos6510.rb b/lib/mos6510/jssid_mos6510.rb index 446a7da..05e7e35 100644 --- a/lib/mos6510/jssid_mos6510.rb +++ b/lib/mos6510/jssid_mos6510.rb @@ -238,15 +238,11 @@ def setflags(flag, cond) def push(val) self.setmem(0x100 + self.s, val) - if self.s > 0 - self.s -= 1 - end + self.s = (self.s - 1) & 0xff end def pop - if self.s < 0xff - self.s += 1 - end + self.s = (self.s + 1) & 0xff self.getmem(0x100 + self.s) end @@ -293,13 +289,12 @@ def step when Inst::ADC value = self.getaddr(addr) carry = (self.p & Flag::C) != 0 ? 1 : 0 - self.wval = self.a + value + ((self.p & Flag::C) != 0 ? 1 : 0) + self.wval = self.a + value + carry v = (((self.a & 0x7f) + (value & 0x7f) + carry) >> 7) ^ (self.wval >> 8) self.setflags(Flag::C, self.wval & 0x100) self.a = self.wval & 0xff self.setflags(Flag::Z, self.a == 0) self.setflags(Flag::N, self.a & 0x80) - #puts "ADC setting v: #{v} (value=#{value}, carry=#{carry}, a=#{self.a}, wval=#{self.wval})" self.setflags(Flag::V, v) when Inst::AND self.bval = self.getaddr(addr) @@ -335,11 +330,13 @@ def step self.setflags(Flag::N, self.bval & 0x80) self.setflags(Flag::V, self.bval & 0x40) when Inst::BRK + self.pcinc() self.push(self.pc >> 8) self.push(self.pc & 0xff) self.push(self.p) - self.setflags(Flag::B1, 1) - self.pc = self.getmem(0xfffe) + self.setflags(Flag::B1, true) + self.setflags(Flag::I, true) + self.pc = self.getmem(0xfffe) + (self.getmem(0xffff) << 8) self.cycles += 7 when Inst::CLC self.cycles += 2 @@ -515,20 +512,25 @@ def step self.setflags(Flag::N, self.bval & 0x80) self.setflags(Flag::Z, self.bval == 0) when Inst::RTI - # treat like RTS + self.p = self.pop + self.pc = self.pop + (self.pop << 8) + self.cycles += 6 when Inst::RTS self.wval = self.pop self.wval |= 256 * self.pop self.pc = self.wval + 1 self.cycles += 6 when Inst::SBC - self.bval = self.getaddr(addr) ^ 0xff - self.wval = self.a + self.bval + ((self.p & Flag::C) != 0 ? 1 : 0) + # Almost identical to SBC, just inverting value + value = self.getaddr(addr) ^ 0xff + carry = (self.p & Flag::C) != 0 ? 1 : 0 + self.wval = self.a + value + carry + v = (((self.a & 0x7f) + (value & 0x7f) + carry) >> 7) ^ (self.wval >> 8) self.setflags(Flag::C, self.wval & 0x100) self.a = self.wval & 0xff self.setflags(Flag::Z, self.a == 0) - self.setflags(Flag::N, self.a > 127) - self.setflags(Flag::V, ((self.p & Flag::C) != 0 ? 1 : 0) ^ ((self.p & Flag::N) != 0 ? 1 : 0)) + self.setflags(Flag::N, self.a & 0x80) + self.setflags(Flag::V, v) when Inst::SEC self.cycles += 2 self.setflags(Flag::C, 1) From d30421bd1da068d7c88fa5e1c22836555ff2201f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Friis=20=C3=98stergaard?= Date: Sun, 15 Jan 2023 16:38:04 +0100 Subject: [PATCH 3/3] ADD with binary-coded decimals works --- lib/mos6510/jssid_mos6510.rb | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/lib/mos6510/jssid_mos6510.rb b/lib/mos6510/jssid_mos6510.rb index 05e7e35..550aca7 100644 --- a/lib/mos6510/jssid_mos6510.rb +++ b/lib/mos6510/jssid_mos6510.rb @@ -289,13 +289,24 @@ def step when Inst::ADC value = self.getaddr(addr) carry = (self.p & Flag::C) != 0 ? 1 : 0 - self.wval = self.a + value + carry - v = (((self.a & 0x7f) + (value & 0x7f) + carry) >> 7) ^ (self.wval >> 8) - self.setflags(Flag::C, self.wval & 0x100) + if (self.p & Flag::D) != 0 + value_bcd = (value & 0xf) + (value >> 4 & 0xf) * 10 + a_bcd = (self.a & 0xf) + (self.a >> 4 & 0xf) * 10 + sum = value_bcd + a_bcd + carry + self.wval = (sum % 10) + (((sum / 10) % 10) << 4) + ((sum / 100) << 8) + self.setflags(Flag::C, sum >= 100) + self.setflags(Flag::V, self.wval > 127 || self.wval < -128) + else + self.wval = self.a + value + carry + v = (((self.a & 0x7f) + (value & 0x7f) + carry) >> 7) ^ (self.wval >> 8) + # TODO: Shouldn't this work? + #v = self.wval > 127 || self.wval < -128 + self.setflags(Flag::C, self.wval & 0x100) + self.setflags(Flag::V, v) + end self.a = self.wval & 0xff - self.setflags(Flag::Z, self.a == 0) self.setflags(Flag::N, self.a & 0x80) - self.setflags(Flag::V, v) + self.setflags(Flag::Z, self.a == 0) when Inst::AND self.bval = self.getaddr(addr) self.a &= self.bval