From 467ec78e894c8184144bfac039dc7d780abbd050 Mon Sep 17 00:00:00 2001 From: krolxon Date: Thu, 8 Jan 2026 19:21:43 +0530 Subject: add SYS instruction --- src/assembler.rs | 7 +++++++ src/cpu.rs | 58 +++++++++++++++++++++++++++++++++++++---------------- src/instructions.rs | 2 ++ 3 files changed, 50 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/assembler.rs b/src/assembler.rs index 73dec00..784337b 100644 --- a/src/assembler.rs +++ b/src/assembler.rs @@ -26,6 +26,7 @@ fn is_reg(s: &str) -> bool { fn instr_size(tokens: &[String]) -> u16 { match tokens[0].as_str() { "mov" | "add" | "sub" | "jmp" | "jz" | "jnz" | "cmp" | "mul" | "div" | "call" => 3, + "sys" => 2, "hlt" | "ret" => 1, _ => panic!("Unknown instruction {}", tokens[0]), } @@ -190,6 +191,12 @@ pub fn assembler(source: &str) -> Vec { bytes.push(Instruction::HLT as u8); } + "sys" => { + let imm = tokens[1].parse().unwrap(); + bytes.push(Instruction::SYS as u8); + bytes.push(imm); + } + _ => panic!("Line {}: unknown instruction", line_no + 1), } } diff --git a/src/cpu.rs b/src/cpu.rs index 1393e95..4fad73e 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -69,21 +69,9 @@ impl CPU { x if x == Instruction::CMP_RR as u8 => self.cmp_rr(mem), x if x == Instruction::MUL as u8 => self.mul(mem), x if x == Instruction::DIV as u8 => self.div(mem), - x if x == Instruction::CALL as u8 => { - let low = mem.read(self.pc) as u16; self.inc_pc(); - let high = mem.read(self.pc) as u16; self.inc_pc(); - let addr = (high << 8) | low; - - let return_addr = self.pc; - - self.push16(mem, return_addr); - self.pc = addr; - - }, - x if x == Instruction::RET as u8 => { - let addr = self.pop16(mem); - self.pc = addr; - }, + x if x == Instruction::CALL as u8 => self.call(mem), + x if x == Instruction::RET as u8 => self.ret(mem), + x if x == Instruction::SYS as u8 => self.syscall(mem), x if x == Instruction::HLT as u8 => self.halt(), _ => panic!("Unknown opcode {:02X}", opcode), } @@ -94,12 +82,10 @@ impl CPU { } pub fn inc_sp(&mut self) { - // self.sp += 1; self.sp = self.sp.wrapping_add(1); } pub fn dec_sp(&mut self) { - // self.sp -= 1; self.sp = self.sp.wrapping_sub(1); } @@ -379,6 +365,44 @@ impl CPU { // carry unchanged } + pub fn call(&mut self, mem: &mut Memory ) { + let low = mem.read(self.pc) as u16; self.inc_pc(); + let high = mem.read(self.pc) as u16; self.inc_pc(); + let addr = (high << 8) | low; + + let return_addr = self.pc; + + self.push16(mem, return_addr); + self.pc = addr; + + } + + pub fn ret(&mut self, mem: &mut Memory) { + let addr = self.pop16(mem); + self.pc = addr; + } + + + pub fn syscall(&mut self, mem: &Memory) { + let num = mem.read(self.pc); + self.pc = self.pc.wrapping_add(1); + match num { + 0 => { + // exit + self.halted = true; + } + 1 => { + // print A as number + println!("{}", self.a); + } + 2 => { + // print A as ASCII char + print!("{}", self.a as char); + } + _ => panic!("Unknown syscall {}", num), + } + } + fn get_reg(&self, r: u8) -> u8 { match r { 0 => self.a, diff --git a/src/instructions.rs b/src/instructions.rs index 620b0ad..a0d086f 100644 --- a/src/instructions.rs +++ b/src/instructions.rs @@ -16,6 +16,7 @@ pub enum Instruction { DIV = 0x0D, CALL = 0x0E, RET = 0x0F, + SYS = 0x10, HLT = 0xFF, } @@ -33,6 +34,7 @@ impl Instruction { 0x0D => "DIV", 0x0E => "CALL", 0x0F => "RET", + 0x10 => "SYS", 0xFF => "HLT", _ => "???", -- cgit v1.2.3