From f0f9d5a6af33c8625cdc777839ef17bf52d619ea Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 8 Mar 2018 20:30:22 -0500 Subject: [PATCH] Corrects memptr leakage via BIT, and ld (de/bc/nn), A behaviour. --- .../Clock SignalTests/Z80MemptrTests.swift | 94 ++++++++++++++++--- .../Z80/Implementation/Z80Implementation.hpp | 6 +- Processors/Z80/Implementation/Z80Storage.cpp | 6 +- Processors/Z80/Implementation/Z80Storage.hpp | 2 + 4 files changed, 89 insertions(+), 19 deletions(-) diff --git a/OSBindings/Mac/Clock SignalTests/Z80MemptrTests.swift b/OSBindings/Mac/Clock SignalTests/Z80MemptrTests.swift index 63be6371a..804407f53 100644 --- a/OSBindings/Mac/Clock SignalTests/Z80MemptrTests.swift +++ b/OSBindings/Mac/Clock SignalTests/Z80MemptrTests.swift @@ -23,6 +23,16 @@ class Z80MemptrTests: XCTestCase { return machine.value(for: .memPtr) } + fileprivate func insert16(program: inout [UInt8], address: Int, offset: size_t) { + program[offset] = UInt8(address & 0x00ff) + program[offset + 1] = UInt8(address >> 8) + } + + /* + Re: comments below: + All the CPU chips tested give the same results except KP1858BM1 and T34BM1 slices noted as "BM1". + */ + // LD A, (addr) func testLDAnn() { // MEMPTR = addr+1 @@ -39,11 +49,40 @@ class Z80MemptrTests: XCTestCase { } } - /* TODO: - LD (addr),A - MEMPTR_low = (addr + 1) & #FF, MEMPTR_hi = A - Note for *BM1: MEMPTR_low = (addr + 1) & #FF, MEMPTR_hi = 0 - */ + // LD (bc/de),A, and LD (nn),A + func testLDrpA() { + // MEMPTR_low = (addr + 1) & #FF, MEMPTR_hi = A + // Note for *BM1: MEMPTR_low = (addr + 1) & #FF, MEMPTR_hi = 0 + let bcProgram: [UInt8] = [ + 0x02 + ] + let deProgram: [UInt8] = [ + 0x12 + ] + var nnProgram: [UInt8] = [ + 0x32, 0x00, 0x00 + ] + + for addr in 0 ..< 256 { + machine.setValue(UInt16(addr), for: .BC) + machine.setValue(UInt16(addr), for: .DE) + insert16(program: &nnProgram, address: addr, offset: 1) + + for a in 0 ..< 256 { + machine.setValue(UInt16(a), for: .A) + + let expectedResult = UInt16(((addr + 1) & 0xff) + (a << 8)) + + let bcResult = test(program: bcProgram, length: 7, initialValue: 0xffff) + let deResult = test(program: deProgram, length: 7, initialValue: 0xffff) + let nnResult = test(program: nnProgram, length: 13, initialValue: 0xffff) + + XCTAssertEqual(bcResult, expectedResult) + XCTAssertEqual(deResult, expectedResult) + XCTAssertEqual(nnResult, expectedResult) + } + } + } // LD A, (rp) func testLDArp() { @@ -68,19 +107,44 @@ class Z80MemptrTests: XCTestCase { } } - /* TODO: - LD (rp),A where rp -- BC or DE - MEMPTR_low = (rp + 1) & #FF, MEMPTR_hi = A - Note for *BM1: MEMPTR_low = (rp + 1) & #FF, MEMPTR_hi = 0 - */ + // LD (addr), rp + func testLDnnrp() { + // MEMPTR = addr + 1 + var ldnnhlBaseProgram: [UInt8] = [ + 0x22, 0x00, 0x00 + ] + var ldnnbcEDProgram: [UInt8] = [ + 0xed, 0x43, 0x00, 0x00 + ] + var ldnndeEDProgram: [UInt8] = [ + 0xed, 0x53, 0x00, 0x00 + ] + var ldnnhlEDProgram: [UInt8] = [ + 0xed, 0x63, 0x00, 0x00 + ] + var ldnnspEDProgram: [UInt8] = [ + 0xed, 0x73, 0x00, 0x00 + ] - /* TODO: - LD (addr), rp - MEMPTR = addr + 1 - */ + for addr in 0 ..< 65536 { + insert16(program: &ldnnhlBaseProgram, address: addr, offset: 1) + insert16(program: &ldnnbcEDProgram, address: addr, offset: 2) + insert16(program: &ldnndeEDProgram, address: addr, offset: 2) + insert16(program: &ldnnhlEDProgram, address: addr, offset: 2) + insert16(program: &ldnnspEDProgram, address: addr, offset: 2) + + let expectedResult = UInt16((addr + 1) & 0xffff) + + XCTAssertEqual(test(program: ldnnhlBaseProgram, length: 16, initialValue: expectedResult ^ 1), expectedResult) + XCTAssertEqual(test(program: ldnnbcEDProgram, length: 20, initialValue: expectedResult ^ 1), expectedResult) + XCTAssertEqual(test(program: ldnndeEDProgram, length: 20, initialValue: expectedResult ^ 1), expectedResult) + XCTAssertEqual(test(program: ldnnhlEDProgram, length: 20, initialValue: expectedResult ^ 1), expectedResult) + XCTAssertEqual(test(program: ldnnspEDProgram, length: 20, initialValue: expectedResult ^ 1), expectedResult) + } + } // LD rp, (addr) - func testLDnnrp() { + func testLDrpnn() { // MEMPTR = addr+1 var hlBaseProgram: [UInt8] = [ 0x22, 0x00, 0x00 diff --git a/Processors/Z80/Implementation/Z80Implementation.hpp b/Processors/Z80/Implementation/Z80Implementation.hpp index 7f1442a4c..ea4d02859 100644 --- a/Processors/Z80/Implementation/Z80Implementation.hpp +++ b/Processors/Z80/Implementation/Z80Implementation.hpp @@ -621,7 +621,7 @@ template < class T, case MicroOp::BIT: { uint8_t result = *static_cast(operation->source) & (1 << ((operation_ >> 3)&7)); - if(current_instruction_page_->is_indexed || ((operation_&0x08) == 7)) { + if(current_instruction_page_->is_indexed || ((operation_&0x07) == 6)) { bit53_result_ = memptr_.bytes.high; } else { bit53_result_ = *static_cast(operation->source); @@ -848,6 +848,10 @@ template < class T, memptr_.full = static_cast(*static_cast(operation->source) + (int8_t)temp8_); break; + case MicroOp::SetAddrAMemptr: + memptr_.full = static_cast(((*static_cast(operation->source) + 1)&0xff) + (a_ << 8)); + break; + case MicroOp::IndexedPlaceHolder: return; } diff --git a/Processors/Z80/Implementation/Z80Storage.cpp b/Processors/Z80/Implementation/Z80Storage.cpp index 15ebfdc50..7189ec72f 100644 --- a/Processors/Z80/Implementation/Z80Storage.cpp +++ b/Processors/Z80/Implementation/Z80Storage.cpp @@ -351,7 +351,7 @@ void ProcessorStorage::assemble_base_page(InstructionPage &target, RegisterPair InstructionTable base_program_table = { /* 0x00 NOP */ NOP, /* 0x01 LD BC, nn */ StdInstr(Read16Inc(pc_, bc_)), - /* 0x02 LD (BC), A */ StdInstr({MicroOp::Move16, &bc_.full, &memptr_.full}, Write3(memptr_, a_)), + /* 0x02 LD (BC), A */ StdInstr({MicroOp::SetAddrAMemptr, &bc_.full}, Write3(bc_, a_)), /* 0x03 INC BC; 0x04 INC B; 0x05 DEC B; 0x06 LD B, n */ INC_INC_DEC_LD(bc_, bc_.bytes.high), @@ -366,7 +366,7 @@ void ProcessorStorage::assemble_base_page(InstructionPage &target, RegisterPair /* 0x0f RRCA */ StdInstr({MicroOp::RRCA}), /* 0x10 DJNZ */ Instr(6, ReadInc(pc_, temp8_), {MicroOp::DJNZ}, InternalOperation(10), {MicroOp::CalculateIndexAddress, &pc_.full}, {MicroOp::Move16, &memptr_.full, &pc_.full}), /* 0x11 LD DE, nn */ StdInstr(Read16Inc(pc_, de_)), - /* 0x12 LD (DE), A */ StdInstr({MicroOp::Move16, &de_.full, &memptr_.full}, Write3(memptr_, a_)), + /* 0x12 LD (DE), A */ StdInstr({MicroOp::SetAddrAMemptr, &de_.full}, Write3(de_, a_)), /* 0x13 INC DE; 0x14 INC D; 0x15 DEC D; 0x16 LD D, n */ INC_INC_DEC_LD(de_, de_.bytes.high), @@ -395,7 +395,7 @@ void ProcessorStorage::assemble_base_page(InstructionPage &target, RegisterPair /* 0x2f CPL */ StdInstr({MicroOp::CPL}), /* 0x30 JR NC */ JR(TestNC), /* 0x31 LD SP, nn */ StdInstr(Read16Inc(pc_, sp_)), - /* 0x32 LD (nn), A */ StdInstr(Read16Inc(pc_, temp16_), Write3(temp16_, a_)), + /* 0x32 LD (nn), A */ StdInstr(Read16Inc(pc_, temp16_), {MicroOp::SetAddrAMemptr, &temp16_.full}, Write3(temp16_, a_)), /* 0x33 INC SP */ Instr(8, {MicroOp::Increment16, &sp_.full}), /* 0x34 INC (HL) */ StdInstr(INDEX(), Read4(INDEX_ADDR(), temp8_), {MicroOp::Increment8, &temp8_}, Write3(INDEX_ADDR(), temp8_)), /* 0x35 DEC (HL) */ StdInstr(INDEX(), Read4(INDEX_ADDR(), temp8_), {MicroOp::Decrement8, &temp8_}, Write3(INDEX_ADDR(), temp8_)), diff --git a/Processors/Z80/Implementation/Z80Storage.hpp b/Processors/Z80/Implementation/Z80Storage.hpp index 9dd45179a..acc147c90 100644 --- a/Processors/Z80/Implementation/Z80Storage.hpp +++ b/Processors/Z80/Implementation/Z80Storage.hpp @@ -91,6 +91,8 @@ class ProcessorStorage { IndexedPlaceHolder, + SetAddrAMemptr, + Reset }; Type type;