summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/interpreter.rs41
1 files changed, 36 insertions, 5 deletions
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;
     }