summaryrefslogtreecommitdiff
path: root/src/core.rs
diff options
context:
space:
mode:
authorOxore <oxore@protonmail.com>2019-11-18 03:52:12 +0300
committerOxore <oxore@protonmail.com>2019-11-18 03:52:12 +0300
commit8b7dbd123183d0dd648d7897eeece1bbfcfe4a0f (patch)
tree12430fe1e7b714439f26573925e526491c0eae39 /src/core.rs
parent4a0a8437263bfb8ac5ead4b1d38c174f8a006e14 (diff)
Implement AJMP instruction
Diffstat (limited to 'src/core.rs')
-rw-r--r--src/core.rs78
1 files changed, 78 insertions, 0 deletions
diff --git a/src/core.rs b/src/core.rs
index 10bb05b..01ec71f 100644
--- a/src/core.rs
+++ b/src/core.rs
@@ -36,6 +36,7 @@ pub enum Operand {
Data(u8),
Register(Register),
Reladdr(i8),
+ Addr11(u16),
}
#[derive(Debug, Clone)]
@@ -57,9 +58,17 @@ const RAM_OFFSET_R6: u8 = 0x06;
const RAM_OFFSET_R7: u8 = 0x07;
const OPCODE_NOP: u8 = 0x00;
+const OPCODE_AJMP_P0: u8 = 0x01;
+const OPCODE_AJMP_P1: u8 = 0x21;
+const OPCODE_AJMP_P2: u8 = 0x41;
+const OPCODE_AJMP_P3: u8 = 0x61;
const OPCODE_MOV_A_DATA: u8 = 0x74;
const OPCODE_MOV_DIRECT_DATA: u8 = 0x75;
const OPCODE_SJMP: u8 = 0x80;
+const OPCODE_AJMP_P4: u8 = 0x81;
+const OPCODE_AJMP_P5: u8 = 0xA1;
+const OPCODE_AJMP_P6: u8 = 0xC1;
+const OPCODE_AJMP_P7: u8 = 0xE1;
const OPCODE_MOV_A_DIRECT: u8 = 0xE5;
const OPCODE_MOV_A_INDIRECT_R0: u8 = 0xE6;
const OPCODE_MOV_A_INDIRECT_R1: u8 = 0xE7;
@@ -87,6 +96,30 @@ const OP_LUT: [Isa8051Op; u8::max_value() as usize + 1] = {
operand1: None,
operand2: None,
};
+ lut[OPCODE_AJMP_P0 as usize] = Isa8051Op {
+ opcode: Isa8051Opcode::Ajmp,
+ size: 2,
+ operand1: Some(Isa8051Operand::Addr11(0)),
+ operand2: None,
+ };
+ lut[OPCODE_AJMP_P1 as usize] = Isa8051Op {
+ opcode: Isa8051Opcode::Ajmp,
+ size: 2,
+ operand1: Some(Isa8051Operand::Addr11(1)),
+ operand2: None,
+ };
+ lut[OPCODE_AJMP_P2 as usize] = Isa8051Op {
+ opcode: Isa8051Opcode::Ajmp,
+ size: 2,
+ operand1: Some(Isa8051Operand::Addr11(2)),
+ operand2: None,
+ };
+ lut[OPCODE_AJMP_P3 as usize] = Isa8051Op {
+ opcode: Isa8051Opcode::Ajmp,
+ size: 2,
+ operand1: Some(Isa8051Operand::Addr11(3)),
+ operand2: None,
+ };
lut[OPCODE_MOV_A_DATA as usize] = Isa8051Op {
opcode: Isa8051Opcode::Mov,
size: 2,
@@ -105,6 +138,30 @@ const OP_LUT: [Isa8051Op; u8::max_value() as usize + 1] = {
operand1: Some(Isa8051Operand::Reladdr),
operand2: None,
};
+ lut[OPCODE_AJMP_P4 as usize] = Isa8051Op {
+ opcode: Isa8051Opcode::Ajmp,
+ size: 2,
+ operand1: Some(Isa8051Operand::Addr11(4)),
+ operand2: None,
+ };
+ lut[OPCODE_AJMP_P5 as usize] = Isa8051Op {
+ opcode: Isa8051Opcode::Ajmp,
+ size: 2,
+ operand1: Some(Isa8051Operand::Addr11(5)),
+ operand2: None,
+ };
+ lut[OPCODE_AJMP_P6 as usize] = Isa8051Op {
+ opcode: Isa8051Opcode::Ajmp,
+ size: 2,
+ operand1: Some(Isa8051Operand::Addr11(6)),
+ operand2: None,
+ };
+ lut[OPCODE_AJMP_P7 as usize] = Isa8051Op {
+ opcode: Isa8051Opcode::Ajmp,
+ size: 2,
+ operand1: Some(Isa8051Operand::Addr11(7)),
+ operand2: None,
+ };
lut[OPCODE_MOV_A_DIRECT as usize] = Isa8051Op {
opcode: Isa8051Opcode::Mov,
size: 2,
@@ -198,6 +255,7 @@ impl fmt::Display for Operand {
Operand::Data(data) => format!("#{}", data),
Operand::Register(r) => format!("{:?}", r),
Operand::Reladdr(rel) => format!("{}", rel),
+ Operand::Addr11(rel) => format!("{}", rel),
}
)
}
@@ -226,6 +284,7 @@ impl Operand {
Operand::Data(_) => 1,
Operand::Register(_) => 0,
Operand::Reladdr(_) => 1,
+ Operand::Addr11(_) => 1,
}
}
}
@@ -315,6 +374,16 @@ impl Core {
panic!("SJMP has no operand given")
}
}
+ Isa8051Opcode::Ajmp => {
+ if let Some(operand) = op.operand1 {
+ match operand {
+ Operand::Addr11(addr) => self.ajmp(addr),
+ _ => panic!("AJMP got incompatible operand"),
+ }
+ } else {
+ panic!("AJMP has no operand given")
+ }
+ }
}
}
@@ -341,6 +410,10 @@ impl Core {
self.pc = (self.pc as i16 + i16::from(reladdr)) as u16;
}
+ fn ajmp(&mut self, pageaddr: u16) {
+ self.pc = (self.pc & !0x4FFu16) + pageaddr as u16;
+ }
+
fn map_operand(&self, operand: Isa8051Operand, offset: usize) -> Operand {
match operand {
Isa8051Operand::Acc => Operand::Acc,
@@ -351,6 +424,9 @@ impl Core {
Isa8051Operand::Reladdr => {
Operand::Reladdr(self.rom.array[(self.pc as usize + offset)] as i8)
}
+ Isa8051Operand::Addr11(high) => Operand::Addr11(
+ self.rom.array[(self.pc as usize + offset)] as u16 + (u16::from(high) << 8),
+ ),
}
}
}
@@ -363,11 +439,13 @@ pub enum Isa8051Operand {
Indirect(Register),
Register(Register),
Reladdr,
+ Addr11(u8),
}
#[derive(Debug, Clone, Copy)]
pub enum Isa8051Opcode {
Nop,
+ Ajmp,
Mov,
Push,
Pop,