From 3e51fca06d097698add372c1052751b3b6313be3 Mon Sep 17 00:00:00 2001 From: Ashelyn Rose Date: Fri, 6 Dec 2024 22:52:55 -0700 Subject: Allow gestalt for glk --- src/interpreter.rs | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/interpreter.rs b/src/interpreter.rs index 800ebf0..ebddcf6 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -6,6 +6,7 @@ pub type MemAddress = u32; pub type StackAddress = u32; pub type FunctionPointer = MemAddress; +#[repr(u32)] enum StubDestType { DoNotStore = 0, MainMemory = 1, @@ -358,9 +359,14 @@ impl Interpreter { crate::instructions::OpCode::Streamstr => todo!(), crate::instructions::OpCode::Streamunichar => todo!(), crate::instructions::OpCode::Gestalt => { - let _gestalt_num = self.eval_source_operand(&instruction.operands[0]); - let _extra_arg = self.eval_source_operand(&instruction.operands[1]); - self.store_dest_operand(&instruction.operands[2], 0); + let gestalt_num = self.eval_source_operand(&instruction.operands[0]); + let extra_arg = self.eval_source_operand(&instruction.operands[1]); + + if gestalt_num == 4 && extra_arg == 2 { + self.store_dest_operand(&instruction.operands[2], 1); + } else { + self.store_dest_operand(&instruction.operands[2], 0); + } }, crate::instructions::OpCode::Debugtrap => todo!(), crate::instructions::OpCode::Getmemsize => todo!(), @@ -471,6 +477,7 @@ impl Interpreter { self.create_return_stub(dest_type, dest_addr, self.reg_program, self.reg_frame); let new_program_counter = self.create_stack_frame(func_addr, args); + println!("Jumping to function at 0x{new_program_counter:04x}"); self.reg_program = new_program_counter; } @@ -558,7 +565,6 @@ impl Interpreter { if !args_in_locals { args.reverse(); for arg in args { - println!("Adding value to stack {arg}"); self.push_stack(arg); } } @@ -567,7 +573,31 @@ impl Interpreter { } fn return_from_function(&mut self, value: u32) { - todo!("Return not implemented"); + // Discard frame + self.reg_stack = self.reg_frame - 4; + + let frame_pointer = self.pop_stack(); + let program_counter = self.pop_stack(); + let dest_addr = self.pop_stack(); + let dest_type = self.pop_stack(); + let dest_type : StubDestType = unsafe {std::mem::transmute(dest_type)}; + + self.reg_frame = frame_pointer; + self.reg_program = program_counter; + + let locals_offset = self.get_word(self.reg_frame + 4, ReadWriteDest::Stack); + + match dest_type { + StubDestType::DoNotStore => (), + StubDestType::MainMemory => self.write_word(dest_addr, ReadWriteDest::Memory, value), + StubDestType::LocalVariable => self.write_word(self.reg_frame + locals_offset, ReadWriteDest::Stack, value), + StubDestType::PushOnStack => self.push_stack(value), + StubDestType::ResumeCompressedString => todo!(), + StubDestType::ResumeFunctionFromString => todo!(), + StubDestType::ResumeInteger => todo!(), + StubDestType::ResumeCString => todo!(), + StubDestType::ResumeUnicodeString => todo!(), + } } fn jump_with_offset(&mut self, offset: u32) { @@ -582,6 +612,7 @@ impl Interpreter { self.reg_program + offset as u32 }; + println!("Jumping {offset} to 0x{destination:04x}"); self.reg_program = destination; } -- cgit 1.4.1