From d8977d32d3eb6f6617b57f2bcea15dbb6f3f0f2a Mon Sep 17 00:00:00 2001 From: "Adrian.Conlon" Date: Wed, 7 Jun 2017 22:54:55 +0100 Subject: [PATCH] More MEMPTR clarifications. This time to avoid temporary variables, in a similar manner to Z80 hardware. Signed-off-by: Adrian.Conlon --- Intel8080/inc/Intel8080.h | 29 +++++---- Z80/inc/Z80.h | 45 +++++++------- Z80/src/Z80.cpp | 121 ++++++++++++++++++++------------------ inc/Processor.h | 10 ++-- src/Processor.cpp | 8 +-- 5 files changed, 110 insertions(+), 103 deletions(-) diff --git a/Intel8080/inc/Intel8080.h b/Intel8080/inc/Intel8080.h index 104a0a5..96f31c6 100644 --- a/Intel8080/inc/Intel8080.h +++ b/Intel8080/inc/Intel8080.h @@ -135,6 +135,14 @@ namespace EightBit { // + register16_t fetchWord() { + register16_t returned; + Processor::fetchWord(returned); + return returned; + } + + // + void compare(uint8_t value) { uint16_t subtraction = A() - value; adjustSZP((uint8_t)subtraction); @@ -325,9 +333,9 @@ namespace EightBit { m_memory.set(HL().word, data); } - void lxi_b() { BC() = fetchWord(); } - void lxi_d() { DE() = fetchWord(); } - void lxi_h() { HL() = fetchWord(); } + void lxi_b() { Processor::fetchWord(BC()); } + void lxi_d() { Processor::fetchWord(DE()); } + void lxi_h() { Processor::fetchWord(HL()); } void stax_b() { m_memory.set(BC().word, A()); } void stax_d() { m_memory.set(DE().word, A()); } @@ -371,14 +379,13 @@ namespace EightBit { pushWord(pair); } - void pop_b() { BC() = popWord(); } - void pop_d() { DE() = popWord(); } - void pop_h() { HL() = popWord(); } + void pop_b() { popWord(BC()); } + void pop_d() { popWord(DE()); } + void pop_h() { popWord(HL()); } void pop_psw() { - auto af = popWord(); - A() = af.high; - F() = af.low; + F() = pop(); + A() = pop(); } void xhtl() { @@ -392,7 +399,7 @@ namespace EightBit { } void lxi_sp() { - sp = fetchWord(); + Processor::fetchWord(sp); } void inx_sp() { ++sp.word; } @@ -440,7 +447,7 @@ namespace EightBit { // return void ret() { - pc = popWord(); + popWord(pc); } void rc() { returnConditional(F().C); } diff --git a/Z80/inc/Z80.h b/Z80/inc/Z80.h index c3d6c2f..87ea8df 100644 --- a/Z80/inc/Z80.h +++ b/Z80/inc/Z80.h @@ -131,6 +131,10 @@ namespace EightBit { std::array m_halfCarryTableAdd = { { false, false, true, false, true, false, true, true } }; std::array m_halfCarryTableSub = { { false, true, true, true, false, false, false, true } }; + void fetchWord() { + Processor::fetchWord(MEMPTR()); + } + int fetchExecute() { M1() = true; return execute(fetchByteExecute()); @@ -251,40 +255,33 @@ namespace EightBit { } } - uint8_t getViaMemptr(register16_t address) { - m_memory.ADDRESS() = address; - MEMPTR().word = address.word + 1; + uint8_t getViaMemptr() { + m_memory.ADDRESS() = MEMPTR(); + MEMPTR().word++; return m_memory.reference(); } - void setViaMemptr(register16_t address, uint8_t value) { - m_memory.ADDRESS() = address; + void setViaMemptr(uint8_t value) { + m_memory.ADDRESS() = MEMPTR(); + MEMPTR().word++; m_memory.reference() = value; - ++address.word; - MEMPTR().low = address.low; MEMPTR().high = value; } - register16_t getWordViaMemptr(register16_t address) { - register16_t returned; - m_memory.ADDRESS() = address; - returned.low = m_memory.reference(); + void getWordViaMemptr(register16_t& value) { + m_memory.ADDRESS() = MEMPTR(); + MEMPTR().word++; + value.low = m_memory.reference(); m_memory.ADDRESS().word++; - returned.high = m_memory.reference(); - MEMPTR() = m_memory.ADDRESS(); - return returned; + value.high = m_memory.reference(); } - void setWordViaMemptr(register16_t address, register16_t value) { - m_memory.ADDRESS() = address; + void setWordViaMemptr(register16_t value) { + m_memory.ADDRESS() = MEMPTR(); + MEMPTR().word++; m_memory.reference() = value.low; m_memory.ADDRESS().word++; m_memory.reference() = value.high; - MEMPTR() = m_memory.ADDRESS(); - } - - void setPcViaMemptr(register16_t address) { - MEMPTR() = pc = address; } void addViaMemptr(register16_t& hl, register16_t operand) { @@ -365,9 +362,9 @@ namespace EightBit { void jumpConditional(int condition); void jumpConditionalFlag(int flag); - void call(register16_t address); - void callConditional(register16_t address, int condition); - void callConditionalFlag(register16_t address, int flag); + void call(); + void callConditional(int condition); + void callConditionalFlag(int flag); void sbc(register16_t& operand, register16_t value); void adc(register16_t& operand, register16_t value); diff --git a/Z80/src/Z80.cpp b/Z80/src/Z80.cpp index e122baa..a5a2cf1 100644 --- a/Z80/src/Z80.cpp +++ b/Z80/src/Z80.cpp @@ -167,17 +167,15 @@ void EightBit::Z80::postDecrement(uint8_t value) { void EightBit::Z80::restart(uint8_t address) { pushWord(pc); - register16_t destination; - destination.word = address; - setPcViaMemptr(destination); + pc.low = MEMPTR().low = address; + pc.high = MEMPTR().high = 0; } void EightBit::Z80::jrConditional(int conditional) { auto offset = (int8_t)fetchByteData(); if (conditional) { - register16_t destination; - destination.word = pc.word + offset; - setPcViaMemptr(destination); + MEMPTR().word = pc.word + offset; + pc = MEMPTR(); cycles += 5; } } @@ -212,10 +210,8 @@ void EightBit::Z80::jrConditionalFlag(int flag) { } void EightBit::Z80::jumpConditional(int conditional) { - auto address = fetchWord(); if (conditional) - pc = address; - MEMPTR() = address; + pc = MEMPTR(); } void EightBit::Z80::jumpConditionalFlag(int flag) { @@ -248,7 +244,8 @@ void EightBit::Z80::jumpConditionalFlag(int flag) { } void EightBit::Z80::ret() { - setPcViaMemptr(popWord()); + popWord(MEMPTR()); + pc = MEMPTR(); } void EightBit::Z80::retn() { @@ -296,44 +293,42 @@ void EightBit::Z80::returnConditionalFlag(int flag) { } } -void EightBit::Z80::call(register16_t address) { +void EightBit::Z80::call() { pushWord(pc); - pc = address; + pc = MEMPTR(); + cycles += 7; } -void EightBit::Z80::callConditional(register16_t address, int condition) { - if (condition) { - call(address); - cycles += 7; - } - MEMPTR() = address; +void EightBit::Z80::callConditional(int condition) { + if (condition) + call(); } -void EightBit::Z80::callConditionalFlag(register16_t address, int flag) { +void EightBit::Z80::callConditionalFlag(int flag) { switch (flag) { case 0: // NZ - callConditional(address, !(F() & ZF)); + callConditional(!(F() & ZF)); break; case 1: // Z - callConditional(address, F() & ZF); + callConditional(F() & ZF); break; case 2: // NC - callConditional(address, !(F() & CF)); + callConditional(!(F() & CF)); break; case 3: // C - callConditional(address, F() & CF); + callConditional(F() & CF); break; case 4: // PO - callConditional(address, !(F() & PF)); + callConditional(!(F() & PF)); break; case 5: // PE - callConditional(address, F() & PF); + callConditional(F() & PF); break; case 6: // P - callConditional(address, !(F() & SF)); + callConditional(!(F() & SF)); break; case 7: // M - callConditional(address, F() & SF); + callConditional(F() & SF); break; } } @@ -775,27 +770,25 @@ void EightBit::Z80::lddr() { #pragma region Block input instructions void EightBit::Z80::ini() { - auto bc = BC().word; - m_memory.ADDRESS().word = bc; + MEMPTR() = m_memory.ADDRESS() = BC(); + MEMPTR().word++; readPort(); auto value = m_memory.DATA(); m_memory.ADDRESS().word = HL().word++; m_memory.reference() = value; postDecrement(--B()); setFlag(NF); - MEMPTR().word = ++bc; } void EightBit::Z80::ind() { - auto bc = BC().word; - m_memory.ADDRESS().word = bc; + MEMPTR() = m_memory.ADDRESS() = BC(); + MEMPTR().word--; readPort(); auto value = m_memory.DATA(); m_memory.ADDRESS().word = HL().word--; m_memory.reference() = value; postDecrement(--B()); setFlag(NF); - MEMPTR().word = --bc; } void EightBit::Z80::inir() { @@ -863,27 +856,27 @@ void EightBit::Z80::otdr() { #pragma region Nibble rotation void EightBit::Z80::rrd() { - auto accumulator = A(); - m_memory.ADDRESS() = HL(); + MEMPTR() = m_memory.ADDRESS() = HL(); + MEMPTR().word++; auto memory = m_memory.reference(); + auto accumulator = A(); A() = (accumulator & 0xf0) | lowNibble(memory); uint8_t updated = promoteNibble(lowNibble(accumulator)) | highNibble(memory); m_memory.reference() = updated; adjustSZPXY(A()); clearFlag(NF | HC); - MEMPTR().word = HL().word + 1; } void EightBit::Z80::rld() { - auto accumulator = A(); - m_memory.ADDRESS() = HL(); + MEMPTR() = m_memory.ADDRESS() = HL(); + MEMPTR().word++; auto memory = m_memory.reference(); + auto accumulator = A(); uint8_t updated = lowNibble(accumulator) | promoteNibble(memory); A() = (accumulator & 0xf0) | highNibble(memory); m_memory.reference() = updated; adjustSZPXY(A()); clearFlag(NF | HC); - MEMPTR().word = HL().word + 1; } #pragma endregion Nibble rotation @@ -1060,22 +1053,22 @@ void EightBit::Z80::executeED(int x, int y, int z, int p, int q) { switch (z) { case 0: // Input from port with 16-bit address MEMPTR() = m_memory.ADDRESS() = BC(); + MEMPTR().word++; readPort(); if (y != 6) // IN r[y],(C) R(y) = m_memory.DATA(); adjustSZPXY(m_memory.DATA()); clearFlag(HC | NF); - MEMPTR().word++; cycles += 12; break; case 1: // Output to port with 16-bit address MEMPTR() = m_memory.ADDRESS() = BC(); + MEMPTR().word++; if (y == 6) // OUT (C),0 m_memory.placeDATA(0); else // OUT (C),r[y] m_memory.placeDATA(R(y)); writePort(); - MEMPTR().word++; cycles += 12; break; case 2: // 16-bit add/subtract with carry @@ -1092,10 +1085,12 @@ void EightBit::Z80::executeED(int x, int y, int z, int p, int q) { case 3: // Retrieve/store register pair from/to immediate address switch (q) { case 0: // LD (nn), rp[p] - setWordViaMemptr(fetchWord(), RP(p)); + fetchWord(); + setWordViaMemptr(RP(p)); break; case 1: // LD rp[p], (nn) - RP(p) = getWordViaMemptr(fetchWord()); + fetchWord(); + getWordViaMemptr(RP(p)); break; } cycles += 20; @@ -1276,8 +1271,8 @@ void EightBit::Z80::executeOther(int x, int y, int z, int p, int q) { break; case 1: // 16-bit load immediate/add switch (q) { - case 0: // LD rp,nn - RP(p) = fetchWord(); + case 0: // LD rp,nn + Processor::fetchWord(RP(p)); cycles += 10; break; case 1: // ADD HL,rp @@ -1291,19 +1286,23 @@ void EightBit::Z80::executeOther(int x, int y, int z, int p, int q) { case 0: switch (p) { case 0: // LD (BC),A - setViaMemptr(BC(), A()); + MEMPTR() = BC(); + setViaMemptr(A()); cycles += 7; break; case 1: // LD (DE),A - setViaMemptr(DE(), A()); + MEMPTR() = DE(); + setViaMemptr(A()); cycles += 7; break; case 2: // LD (nn),HL - setWordViaMemptr(fetchWord(), ALT_HL()); + fetchWord(); + setWordViaMemptr(ALT_HL()); cycles += 16; break; case 3: // LD (nn),A - setViaMemptr(fetchWord(), A()); + fetchWord(); + setViaMemptr(A()); cycles += 13; break; } @@ -1311,19 +1310,23 @@ void EightBit::Z80::executeOther(int x, int y, int z, int p, int q) { case 1: switch (p) { case 0: // LD A,(BC) - A() = getViaMemptr(BC()); + MEMPTR() = BC(); + A() = getViaMemptr(); cycles += 7; break; case 1: // LD A,(DE) - A() = getViaMemptr(DE()); + MEMPTR() = DE(); + A() = getViaMemptr(); cycles += 7; break; case 2: // LD HL,(nn) - ALT_HL() = getWordViaMemptr(fetchWord()); + fetchWord(); + getWordViaMemptr(ALT_HL()); cycles += 16; break; case 3: // LD A,(nn) - A() = getViaMemptr(fetchWord()); + fetchWord(); + A() = getViaMemptr(); cycles += 13; break; } @@ -1466,7 +1469,7 @@ void EightBit::Z80::executeOther(int x, int y, int z, int p, int q) { case 1: // POP & various ops switch (q) { case 0: // POP rp2[p] - RP2(p) = popWord(); + popWord(RP2(p)); cycles += 10; break; case 1: @@ -1491,13 +1494,15 @@ void EightBit::Z80::executeOther(int x, int y, int z, int p, int q) { } break; case 2: // Conditional jump + fetchWord(); jumpConditionalFlag(y); cycles += 10; break; case 3: // Assorted operations switch (y) { case 0: // JP nn - setPcViaMemptr(fetchWord()); + fetchWord(); + pc = MEMPTR(); cycles += 10; break; case 1: // CB prefix @@ -1543,7 +1548,8 @@ void EightBit::Z80::executeOther(int x, int y, int z, int p, int q) { } break; case 4: // Conditional call: CALL cc[y], nn - callConditionalFlag(fetchWord(), y); + fetchWord(); + callConditionalFlag(y); cycles += 10; break; case 5: // PUSH & various ops @@ -1555,7 +1561,8 @@ void EightBit::Z80::executeOther(int x, int y, int z, int p, int q) { case 1: switch (p) { case 0: // CALL nn - callConditional(fetchWord(), true); + fetchWord(); + call(); cycles += 17; break; case 1: // DD prefix diff --git a/inc/Processor.h b/inc/Processor.h index 0587142..f84e51c 100644 --- a/inc/Processor.h +++ b/inc/Processor.h @@ -78,7 +78,7 @@ namespace EightBit { void pushWord(register16_t value); uint8_t pop(); - register16_t popWord(); + void popWord(register16_t& output); uint8_t fetchByte() { m_memory.ADDRESS() = pc; @@ -86,11 +86,9 @@ namespace EightBit { return m_memory.reference(); } - register16_t fetchWord() { - register16_t returned; - returned.low = fetchByte(); - returned.high = fetchByte(); - return returned; + void fetchWord(register16_t& output) { + output.low = fetchByte(); + output.high = fetchByte(); } }; } \ No newline at end of file diff --git a/src/Processor.cpp b/src/Processor.cpp index d41862a..7179e21 100644 --- a/src/Processor.cpp +++ b/src/Processor.cpp @@ -35,9 +35,7 @@ uint8_t EightBit::Processor::pop() { return m_memory.reference(); } -EightBit::register16_t EightBit::Processor::popWord() { - register16_t returned; - returned.low = pop(); - returned.high = pop(); - return returned; +void EightBit::Processor::popWord(register16_t& output) { + output.low = pop(); + output.high = pop(); }