From 553e97d1e5159f2e1dea56dfff0901a029c74f62 Mon Sep 17 00:00:00 2001
From: mrb0nk500 <b0nk@b0nk.xyz>
Date: Mon, 24 Jan 2022 16:29:54 -0400
Subject: sux.h: Add bitmasks for arithmetic operations.

---
 sux.h | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/sux.h b/sux.h
index 19e1c16..a56d094 100644
--- a/sux.h
+++ b/sux.h
@@ -1778,6 +1778,14 @@ static /*inline*/ void exec_base_inst(struct sux *cpu, uint8_t opcode, uint8_t p
 	}
 }
 
+#define shift(reg, value, sign, shift) (((reg) shift (value)) | ((sign)))
+#define rotate(sum, reg, value, shift1, shift2, c1, c2) \
+	switch (value & 0x3F) { \
+		case 0: sum = (reg); break; \
+		case 1: sum = shift(reg, value, c1, shift1); break; \
+		default: sum = shift(reg, value, c2, shift1) | shift(reg, (msb+1)-value, 0, shift2); break; \
+	}
+
 #if 0
 #define t(w8, w7, w6, w5, w4, w3, w2, w1, w0, code) \
 	do { \
@@ -1792,7 +1800,10 @@ static /*inline*/ void exec_base_inst(struct sux *cpu, uint8_t opcode, uint8_t p
 #define inst(op, ext) \
 static /*inline*/ void inst_##op(struct sux *cpu, uint8_t prefix, uint8_t size, int inc_pc, int inc_clk, uint8_t thread) { \
 	const unsigned int o8 = 0x##op / 32, o8m = 1 << (0x##op % 32); \
+	const uint8_t msb = size*8; \
 	uint8_t rs = ((1 << ((prefix >> 4) & 3)) - 1); \
+	uint8_t carry = 0; \
+	uint64_t sign = 0; \
 	uint64_t addr = 0, idx = 0, tmp = 0, tmp2 = 0; \
 	uint64_t dummy = 0, *reg = &dummy; \
 	uint64_t dummy2 = 0, *reg2 = &dummy; \
@@ -1851,6 +1862,20 @@ static /*inline*/ void inst_##op(struct sux *cpu, uint8_t prefix, uint8_t size,
 	/* Set program counter to supplied address */ \
 	t(7, 0x00011000, 0x10010000, 0x00010000, 0x00010001, 0x00000201, 0x00010001, 0x00010001, 0x00010000) { if (tmp) { cpu->pc = addr; } } /* If flag is 1. */ \
 	t(0, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00010000, 0x00000000, 0x00000000, 0x00000000) { if (!tmp) { cpu->pc = addr; } } /* If flag is 0. */ \
+	/* Arithmetic operations. */ \
+	t(0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00440044, 0x00000000, 0x00000000, 0x00000000) { sign = -(uint64_t)(*reg >> (msb-1)) << (msb-1)-tmp2; } /* asr. */ \
+	t(0, 0x00220022, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00220022, 0x00660066) { carry = getflag(C); } /* adc, sbc, and rotate. */ \
+	t(0, 0x06000000, 0x00000000, 0x04000400, 0x00441044, 0x10000000, 0x00100110, 0x00100110, 0x00100110) { carry = 1; } /* cmp, cpb, cpx, and cpy. */ \
+	t(0, 0x06220022, 0x00220022, 0x04220422, 0x00441044, 0x10440044, 0x00540154, 0x00760176, 0x00760176) { tmp2 = tmp; } /* Copy source operand. */ \
+	t(0, 0x06000000, 0x00000000, 0x04000400, 0x00441044, 0x10000000, 0x00100110, 0x00320132, 0x00320132) { tmp += *reg + carry; carry = tmp < tmp2; } /* adc, sbc, and cmp. */ \
+	t(0, 0x00000000, 0x00000000, 0x00220022, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000) { tmp = (tmp2 < msb) ? shift(*reg, tmp2, 0, <<) : 0; } /* lsl. */ \
+	t(0, 0x00000000, 0x00220022, 0x00000000, 0x00000000, 0x00440044, 0x00000000, 0x00000000, 0x00000000) { tmp = (tmp2 < msb) ? shift(*reg, tmp2, sign, >>) : 0; } /* lsr, asr. */ \
+	t(0, 0x00220022, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000) { rotate(tmp, *reg, tmp2, <<, >>, carry & 1, carry << (tmp2-1)); } /* rol. */ \
+	t(0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00440044) { rotate(tmp, *reg, tmp2, >>, <<, carry << (msb-1), carry << (msb-tmp2)); } /* ror. */ \
+	t(0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00440044, 0x00000000) { tmp *= *reg; } /* mul. */ \
+	t(0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00440044, 0x00000000, 0x00000000) { tmp /= *reg; *reg2 %= tmp2; } /* div. */ \
+	t(0, 0x00220022, 0x00000000, 0x00220022, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000) { carry = (*reg >> (msb-(tmp2+!tmp2))) & 1; } /* rol, lsl. */ \
+	t(0, 0x00000000, 0x00220022, 0x00000000, 0x00000000, 0x00440044, 0x00000000, 0x00000000, 0x00440044) { carry = (*reg >> tmp2-(tmp2 != 0)) & 1; } /* ror, lsr, asr. */ \
 }
 
 #undef ORTHO_1CC
-- 
cgit v1.2.3-13-gbd6f