summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2013-10-26 23:15:45 (GMT)
committerH. Peter Anvin <hpa@zytor.com>2013-10-26 23:15:45 (GMT)
commit587a2597988216e3ee1cfe74934e74b5876cea96 (patch)
tree630d02a95ea7be3e4eb1bd79f9f9b87abf48f718
parent735e8b4d7e6f0564f5e969df2c7db8376ce48146 (diff)
downloadabc80sim-587a2597988216e3ee1cfe74934e74b5876cea96.zip
abc80sim-587a2597988216e3ee1cfe74934e74b5876cea96.tar.gz
abc80sim-587a2597988216e3ee1cfe74934e74b5876cea96.tar.bz2
abc80sim-587a2597988216e3ee1cfe74934e74b5876cea96.tar.xz
z80: add the undocumented instruction SLL
Shift left, insert 1. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--z80.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/z80.c b/z80.c
index 9b2f5e5..d142c05 100644
--- a/z80.c
+++ b/z80.c
@@ -773,6 +773,32 @@ static int sla_byte(int value)
return result;
}
+/* SLL is an undocumented instruction which shifts left and sets the LSB */
+static int sll_byte(int value)
+{
+ uint8_t clear, set;
+ int result;
+
+ clear = ~(SIGN_MASK | ZERO_MASK | HALF_CARRY_MASK | PARITY_MASK |
+ SUBTRACT_MASK | CARRY_MASK);
+ set = 0;
+
+ result = (value << 1) | 1;
+
+ if(result & 0x80)
+ set |= SIGN_MASK;
+ if(result == 0)
+ set |= ZERO_MASK;
+ if(parity(result))
+ set |= PARITY_MASK;
+ if(value & 0x80)
+ set |= CARRY_MASK;
+
+ REG_F = (REG_F & clear) | set;
+
+ return result;
+}
+
static int sra_byte(int value)
{
uint8_t clear, set;
@@ -2055,6 +2081,31 @@ static void do_CB_instruction(wordregister *ix)
mem_write(addr, sla_byte(mem_read(addr)));
break;
+ case 0x37: /* sll a */
+ REG_A = sll_byte(REG_A);
+ break;
+ case 0x30: /* sll b */
+ REG_B = sll_byte(REG_B);
+ break;
+ case 0x31: /* sll c */
+ REG_C = sll_byte(REG_C);
+ break;
+ case 0x32: /* sll d */
+ REG_D = sll_byte(REG_D);
+ break;
+ case 0x33: /* sll e */
+ REG_E = sll_byte(REG_E);
+ break;
+ case 0x34: /* sll h */
+ ix->byte.high = sll_byte(ix->byte.high);
+ break;
+ case 0x35: /* sll l */
+ ix->byte.low = sll_byte(ix->byte.low);
+ break;
+ case 0x36: /* sll (hl) */
+ mem_write(addr, sll_byte(mem_read(addr)));
+ break;
+
case 0x2F: /* sra a */
REG_A = sra_byte(REG_A);
break;