mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-11 08:30:55 +00:00
Corrects memptr leakage via BIT, and ld (de/bc/nn), A behaviour.
This commit is contained in:
parent
03501df9e5
commit
f0f9d5a6af
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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_)),
|
||||
|
@ -91,6 +91,8 @@ class ProcessorStorage {
|
||||
|
||||
IndexedPlaceHolder,
|
||||
|
||||
SetAddrAMemptr,
|
||||
|
||||
Reset
|
||||
};
|
||||
Type type;
|
||||
|
Loading…
x
Reference in New Issue
Block a user