summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices
diff options
context:
space:
mode:
author AJR <ajrhacker@users.noreply.github.com>2019-11-15 12:31:07 -0500
committer AJR <ajrhacker@users.noreply.github.com>2019-11-15 12:31:07 -0500
commita0e2b82b634f796c186dec0db895028088a542e9 (patch)
treef0edc37aab4f7506afd85d3b8625976f3d764c32 /src/devices
parent8bafad2751caa05cd6be15ad3b3ebe412d846903 (diff)
mc68hc11: Emulate FDIV instruction
Diffstat (limited to 'src/devices')
-rw-r--r--src/devices/cpu/mc68hc11/hc11ops.h2
-rw-r--r--src/devices/cpu/mc68hc11/hc11ops.hxx36
-rw-r--r--src/devices/cpu/mc68hc11/mc68hc11.h1
3 files changed, 38 insertions, 1 deletions
diff --git a/src/devices/cpu/mc68hc11/hc11ops.h b/src/devices/cpu/mc68hc11/hc11ops.h
index ee8c538a72f..a58dda18144 100644
--- a/src/devices/cpu/mc68hc11/hc11ops.h
+++ b/src/devices/cpu/mc68hc11/hc11ops.h
@@ -149,7 +149,7 @@ const mc68hc11_cpu_device::hc11_opcode_list_struct mc68hc11_cpu_device::hc11_opc
{ 0, 0xf8, &HC11OP(eorb_ext) },
{ 0, 0xe8, &HC11OP(eorb_indx) },
{ 0x18, 0xe8, &HC11OP(eorb_indy) },
-// { 0, 0x03, &HC11OP(fdiv) },
+ { 0, 0x03, &HC11OP(fdiv) },
{ 0, 0x02, &HC11OP(idiv) },
{ 0, 0x4c, &HC11OP(inca) },
{ 0, 0x5c, &HC11OP(incb) },
diff --git a/src/devices/cpu/mc68hc11/hc11ops.hxx b/src/devices/cpu/mc68hc11/hc11ops.hxx
index da168c095d2..7ad9da594ae 100644
--- a/src/devices/cpu/mc68hc11/hc11ops.hxx
+++ b/src/devices/cpu/mc68hc11/hc11ops.hxx
@@ -2099,6 +2099,42 @@ void HC11OP(eorb_indy)()
CYCLES(5);
}
+/* FDIV 0x03 */
+void HC11OP(fdiv)()
+{
+ uint16_t numerator = REG_D;
+ uint16_t denominator = m_ix;
+ uint16_t remainder;
+ uint16_t result;
+
+ CLEAR_ZVC();
+ if(denominator == 0) // divide by zero behaviour
+ {
+ remainder = 0xffff; // TODO: undefined behaviour according to the docs
+ result = 0xffff;
+ logerror("HC11: divide by zero at PC=%04x\n",m_pc-1);
+ m_ccr |= CC_C | CC_V;
+ }
+ else if(denominator <= numerator)
+ {
+ remainder = 0xffff; // TODO: undefined behaviour according to the docs
+ result = 0xffff;
+ logerror("HC11: FDIV overflow at PC=%04x\n",m_pc-1);
+ m_ccr |= CC_V;
+ }
+ else
+ {
+ uint32_t scaled_numerator = numerator * 65536;
+ remainder = scaled_numerator % denominator;
+ result = scaled_numerator / denominator;
+ }
+ m_ix = result;
+ REG_D = remainder;
+ SET_Z16(result);
+
+ CYCLES(41);
+}
+
/* IDIV 0x02 */
void HC11OP(idiv)()
{
diff --git a/src/devices/cpu/mc68hc11/mc68hc11.h b/src/devices/cpu/mc68hc11/mc68hc11.h
index b9f7c237037..56a9998dd0b 100644
--- a/src/devices/cpu/mc68hc11/mc68hc11.h
+++ b/src/devices/cpu/mc68hc11/mc68hc11.h
@@ -345,6 +345,7 @@ private:
void hc11_eorb_ext();
void hc11_eorb_indx();
void hc11_eorb_indy();
+ void hc11_fdiv();
void hc11_idiv();
void hc11_inca();
void hc11_incb();