use super::{
Context,
Op::{self, *},
PasmError::*,
PasmResult,
};
pub fn ldm(ctx: &mut Context, op: &Op) -> PasmResult {
match op {
MultiOp(ops) => match ops[..] {
[ref op, Literal(val)] if op.is_register() => {
*ctx.get_mut_register(op) = val;
Ok(())
}
_ => Err(InvalidMultiOp),
},
&Literal(val) => {
ctx.acc = val;
Ok(())
}
Null => Err(NoOperand),
_ => Err(InvalidOperand),
}
}
pub fn ldd(ctx: &mut Context, op: &Op) -> PasmResult {
match op {
Loc(loc) => {
ctx.acc = ctx.mem.get(loc)?;
Ok(())
}
MultiOp(ops) => match ops[..] {
[ref reg, Loc(ref loc)] if reg.is_register() => {
let x = ctx.mem.get(loc)?;
*ctx.get_mut_register(reg) = x;
Ok(())
}
_ => Err(InvalidMultiOp),
},
Null => Err(NoOperand),
_ => Err(InvalidOperand),
}
}
pub fn ldi(ctx: &mut Context, op: &Op) -> PasmResult {
match op {
Loc(mut loc) => {
loc = ctx.mem.get_address(&loc)?;
ctx.acc = ctx.mem.get(&loc).map_err(|_| InvalidIndirectAddress(loc))?;
Ok(())
}
MultiOp(ops) => match ops[..] {
[ref reg, Loc(mut loc)] if reg.is_register() => {
loc = ctx.mem.get_address(&loc)?;
*ctx.get_mut_register(reg) =
ctx.mem.get(&loc).map_err(|_| InvalidIndirectAddress(loc))?;
Ok(())
}
_ => Err(InvalidMultiOp),
},
Null => Err(NoOperand),
_ => Err(InvalidOperand),
}
}
pub fn ldx(ctx: &mut Context, op: &Op) -> PasmResult {
match op {
Loc(mut loc) => {
loc += ctx.ix;
ctx.acc = ctx.mem.get(&loc).map_err(|_| InvalidIndexedAddress(loc))?;
Ok(())
}
MultiOp(ops) => match ops[..] {
[ref reg, Loc(mut loc)] if reg.is_register() => {
loc += ctx.ix;
*ctx.get_mut_register(reg) =
ctx.mem.get(&loc).map_err(|_| InvalidIndexedAddress(loc))?;
Ok(())
}
_ => Err(InvalidMultiOp),
},
Null => Err(NoOperand),
_ => Err(InvalidOperand),
}
}
pub fn ldr(ctx: &mut Context, op: &Op) -> PasmResult {
match op {
&Literal(val) => ctx.ix = val,
Null => return Err(NoOperand),
_ => return Err(InvalidOperand),
}
Ok(())
}
pub fn mov(ctx: &mut Context, op: &Op) -> PasmResult {
match op {
MultiOp(ops) => match ops[..] {
[ref dest, ref src] if dest.is_read_write() && src.is_usizeable() => {
let src = src.get_val(ctx)?;
ctx.modify(dest, |val| *val = src)?;
}
_ => return Err(InvalidMultiOp),
},
reg if reg.is_register() => *ctx.get_mut_register(reg) = ctx.acc,
Null => return Err(NoOperand),
_ => return Err(InvalidOperand),
}
Ok(())
}
pub fn sto(ctx: &mut Context, op: &Op) -> PasmResult {
match op {
Loc(x) => {
ctx.mem.write(x, ctx.acc)?;
Ok(())
}
Null => Err(NoOperand),
_ => Err(InvalidOperand),
}
}