1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-05 10:28:58 +00:00

Corrects memptr leakage via BIT, and ld (de/bc/nn), A behaviour.

This commit is contained in:
Thomas Harte 2018-03-08 20:30:22 -05:00
parent 03501df9e5
commit f0f9d5a6af
4 changed files with 89 additions and 19 deletions

View File

@ -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

View File

@ -621,7 +621,7 @@ template < class T,
case MicroOp::BIT: {
uint8_t result = *static_cast<uint8_t *>(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<uint8_t *>(operation->source);
@ -848,6 +848,10 @@ template < class T,
memptr_.full = static_cast<uint16_t>(*static_cast<uint16_t *>(operation->source) + (int8_t)temp8_);
break;
case MicroOp::SetAddrAMemptr:
memptr_.full = static_cast<uint16_t>(((*static_cast<uint16_t *>(operation->source) + 1)&0xff) + (a_ << 8));
break;
case MicroOp::IndexedPlaceHolder:
return;
}

View File

@ -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_)),

View File

@ -91,6 +91,8 @@ class ProcessorStorage {
IndexedPlaceHolder,
SetAddrAMemptr,
Reset
};
Type type;