1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
use types::*; impl Instruction<u16> { pub fn encode(&self, output: &mut [u16]) -> u16 { match *self { Instruction::BasicOp(op, b, a) => { let mut i = 1; output[0] = op.encode(); let (val, next) = a.encode(true); output[0] |= val << SHIFT_A; if let Some(n) = next { output[i] = n; i += 1; } let (val, next) = b.encode(false); output[0] |= val << SHIFT_B; if let Some(n) = next { output[i] = n; i += 1; } i as u16 }, Instruction::SpecialOp(op, v) => { let (a_bin, next) = v.encode(true); output[0] = op.encode() << SHIFT_B | (a_bin) << SHIFT_A; if let Some(n) = next { output[1] = n; 2 } else { 1 } } } } } impl Value<u16> { pub fn encode(&self, is_a: bool) -> (u16, Option<u16>) { match *self { Value::Reg(r) => (r.offset(), None), Value::AtReg(r) => (0x08 + r.offset(), None), Value::AtRegPlus(r, v) => (0x10 + r.offset(), Some(v)), Value::Push => (0x18, None), Value::Peek => (0x19, None), Value::Pick(v) => (0x1a, Some(v)), Value::SP => (0x1b, None), Value::PC => (0x1c, None), Value::EX => (0x1d, None), Value::AtAddr(v) => (0x1e, Some(v)), Value::Litteral(v) => { if is_a && (v <= 0x1e || v == 0xffff) { (0x20 + v.wrapping_add(1), None) } else { (0x1f, Some(v)) } } } } } impl BasicOp { pub fn encode(&self) -> u16 { *self as u16 } } impl SpecialOp { pub fn encode(&self) -> u16 { *self as u16 } }