aboutsummaryrefslogtreecommitdiff
path: root/cpu/instructions.go
diff options
context:
space:
mode:
Diffstat (limited to 'cpu/instructions.go')
-rw-r--r--cpu/instructions.go80
1 files changed, 80 insertions, 0 deletions
diff --git a/cpu/instructions.go b/cpu/instructions.go
index b74a2db..b4d4bbe 100644
--- a/cpu/instructions.go
+++ b/cpu/instructions.go
@@ -226,3 +226,83 @@ func jamExec(c *CPU, op operand) {
c.Jammed = true
c.PC--
}
+
+// and with immediate, then carry takes the sign bit
+func ancExec(c *CPU, op operand) {
+ c.A &= c.operandValue(op)
+ c.setZN(c.A)
+ c.setFlag(FlagC, c.A&0x80 != 0)
+}
+
+// and with immediate, then lsr a
+func alrExec(c *CPU, op operand) {
+ v := c.A & c.operandValue(op)
+ c.setFlag(FlagC, v&0x01 != 0)
+ c.A = v >> 1
+ c.setZN(c.A)
+}
+
+// and with immediate, then ror a, but C and V come from bits 6 and 5 of the
+// result (binary mode only, the 2A03 has no decimal mode)
+func arrExec(c *CPU, op operand) {
+ v := c.A & c.operandValue(op)
+ var carryIn uint8
+ if c.flag(FlagC) {
+ carryIn = 0x80
+ }
+ c.A = v>>1 | carryIn
+ c.setZN(c.A)
+ c.setFlag(FlagC, c.A&0x40 != 0)
+ c.setFlag(FlagV, (c.A>>6^c.A>>5)&0x01 != 0)
+}
+
+// x = (a & x) - immediate, like cmp: no borrow in, V untouched
+func axsExec(c *CPU, op operand) {
+ v := c.A & c.X
+ imm := c.operandValue(op)
+ c.setFlag(FlagC, v >= imm)
+ c.X = v - imm
+ c.setZN(c.X)
+}
+
+// memory & sp goes into a, x and sp
+func lasExec(c *CPU, op operand) {
+ v := c.operandValue(op) & c.SP
+ c.A, c.X, c.SP = v, v, v
+ c.setZN(v)
+}
+
+const unstableMagic uint8 = 0xEE
+
+func aneExec(c *CPU, op operand) {
+ c.A = (c.A | unstableMagic) & c.X & c.operandValue(op)
+ c.setZN(c.A)
+}
+
+func lxaExec(c *CPU, op operand) {
+ c.A = (c.A | unstableMagic) & c.operandValue(op)
+ c.X = c.A
+ c.setZN(c.A)
+}
+
+func (c *CPU) storeHighAnd(op operand, v uint8) {
+ baseHi := uint8(op.addr >> 8)
+ if op.pageCrossed {
+ baseHi--
+ }
+ v &= baseHi + 1
+ addr := op.addr
+ if op.pageCrossed {
+ addr = uint16(v)<<8 | addr&0x00FF
+ }
+ c.write(addr, v)
+}
+
+func ahxExec(c *CPU, op operand) { c.storeHighAnd(op, c.A&c.X) }
+func shxExec(c *CPU, op operand) { c.storeHighAnd(op, c.X) }
+func shyExec(c *CPU, op operand) { c.storeHighAnd(op, c.Y) }
+
+func tasExec(c *CPU, op operand) {
+ c.SP = c.A & c.X
+ c.storeHighAnd(op, c.SP)
+}