use opcode_proc::generate_opcodes; use crate::{glk::Glk, interpreter::Output}; generate_opcodes!( pub enum OpCode { #[code(0x00)] fn Nop() { }, #[code(0x10)] fn Add(a: u32, b: u32) -> u32 { a + b }, #[code(0x11)] fn Sub(a: u32, b: u32) -> u32 { a - b }, #[code(0x12)] fn Mul(a: u32, b: u32) -> u32 { a * b }, #[code(0x13)] fn Div(a: u32, b: u32) -> u32 { a / b }, #[code(0x14)] fn Mod(a: u32, b: u32) -> u32 { a % b }, #[code(0x15)] fn Neg(a: u32) -> u32 { -(a as i32) as u32 }, #[code(0x18)] fn Bitand(a: u32, b: u32) -> u32 { a & b }, #[code(0x19)] fn Bitor(a: u32, b: u32) -> u32 { a | b }, #[code(0x1A)] fn Bitxor(a: u32, b: u32) -> u32 { a ^ b }, #[code(0x1B)] fn Bitnot(a: u32) -> u32 { !a }, #[code(0x1C)] fn Shiftl() { todo!() }, #[code(0x1D)] fn Sshiftr() { todo!() }, #[code(0x1E)] fn Ushiftr() { todo!() }, #[code(0x20)] fn Jump() { todo!() }, #[code(0x22)] fn Jz() { todo!() }, #[code(0x23)] fn Jnz(&mut interpreter, comparison: u32, offset: u32) { if comparison != 0 { interpreter.reg_program = interpreter.reg_program + offset - 2; } }, #[code(0x24)] fn Jeq() { todo!(); }, #[code(0x25)] fn Jne() { todo!(); }, #[code(0x26)] fn Jlt() { todo!(); }, #[code(0x27)] fn Jge() { todo!(); }, #[code(0x28)] fn Jgt() { todo!(); }, #[code(0x29)] fn Jle() { todo!(); }, #[code(0x2A)] fn Jltu() { todo!(); }, #[code(0x2B)] fn Jgeu() { todo!(); }, #[code(0x2C)] fn Jgtu() { todo!(); }, #[code(0x2D)] fn Jleu() { todo!(); }, #[code(0x30), no_store] fn Call(&mut interpreter, func_addr: u32, arg_count: u32) -> u32 { let args = (0..arg_count).map(|_| interpreter.pop_stack()).collect::>(); interpreter.create_return_stub(); interpreter.call_function(func_addr, args); // This gets ignored because of gen_return_stub but it's here for type reasons return 0; }, #[code(0x31)] fn Return() { todo!(); }, #[code(0x32)] fn Catch() { todo!(); }, #[code(0x33)] fn Throw() { todo!(); }, #[code(0x34)] fn Tailcall() { todo!(); }, #[code(0x40)] fn Copy(param: u32) -> u32 { return param }, #[code(0x41)] fn Copys() { todo!(); }, #[code(0x42)] fn Copyb() { todo!(); }, #[code(0x44)] fn Sexs() { todo!(); }, #[code(0x45)] fn Sexb() { todo!(); }, #[code(0x48)] fn Aload() { todo!(); }, #[code(0x49)] fn Aloads() { todo!(); }, #[code(0x4A)] fn Aloadb() { todo!(); }, #[code(0x4B)] fn Aloadbit() { todo!(); }, #[code(0x4C)] fn Astore() { todo!(); }, #[code(0x4D)] fn Astores() { todo!(); }, #[code(0x4E)] fn Astoreb() { todo!(); }, #[code(0x4F)] fn Astorebit() { todo!(); }, #[code(0x50)] fn Stkcount() { todo!(); }, #[code(0x51)] fn Stkpeek() { todo!(); }, #[code(0x52)] fn Stkswap() { todo!(); }, #[code(0x53)] fn Stkroll() { todo!(); }, #[code(0x54)] fn Stkcopy() { todo!(); }, #[code(0x70)] fn Streamchar() { todo!(); }, #[code(0x71)] fn Streamnum() { todo!(); }, #[code(0x72)] fn Streamstr() { todo!(); }, #[code(0x73)] fn Streamunichar() { todo!(); }, #[code(0x100)] fn Gestalt(gestalt_selector: u32, extra_arg: u32) -> u32 { match gestalt_selector { // IO System 4 => { return match extra_arg { // Null 0 => 1, 1 => 0, 2 => 1, 20 => 0, _ => 0, } } _ => { println!("WARN: Unknown gestalt {gestalt_selector}"); return 0 } } }, #[code(0x101)] fn Debugtrap() { todo!(); }, #[code(0x102)] fn Getmemsize() { todo!(); }, #[code(0x103)] fn Setmemsize() { todo!(); }, #[code(0x104)] fn Jumpabs() { todo!(); }, #[code(0x110)] fn Random() { todo!(); }, #[code(0x111)] fn Setrandom() { todo!(); }, #[code(0x120)] fn Quit() { println!("Story exited"); std::process::exit(0); }, #[code(0x121)] fn Verify() { todo!(); }, #[code(0x122)] fn Restart() { todo!(); }, #[code(0x123)] fn Save() { todo!(); }, #[code(0x124)] fn Restore() { todo!(); }, #[code(0x125)] fn Saveundo() { todo!(); }, #[code(0x126)] fn Restoreundo() { todo!(); }, #[code(0x127)] fn Protect() { todo!(); }, #[code(0x128)] fn Hasundo() { todo!(); }, #[code(0x129)] fn Discardundo() { todo!(); }, #[code(0x130)] fn Glk() { todo!(); }, #[code(0x140)] fn Getstringtbl() { todo!(); }, #[code(0x141)] fn Setstringtbl() { todo!(); }, #[code(0x148)] fn Getiosys() { todo!(); }, #[code(0x149)] fn Setiosys(&mut interpreter, mode: u32, rock: u32) { match mode { 0 => { interpreter.output_mode = Output::Null; }, 1 => { interpreter.output_mode = Output::Filter(rock); }, 2 => { interpreter.output_mode = Output::Glk(Glk {}, rock); }, 20 => { panic!("This interpreter does not support FyreVM"); }, _ => { panic!("Unknown iosys mode {mode}"); } } }, #[code(0x150)] fn Linearsearch() { todo!(); }, #[code(0x151)] fn Binarysearch() { todo!(); }, #[code(0x152)] fn Linkedsearch() { todo!(); }, #[code(0x160), no_store] fn Callf(&mut interpreter, func_addr: u32) -> u32 { interpreter.create_return_stub(); interpreter.call_function(func_addr, Vec::new()); // This gets ignored because of gen_return_stub but it's here for type reasons return 0; }, #[code(0x161)] fn Callfi() { todo!(); }, #[code(0x162)] fn Callfii() { todo!(); }, #[code(0x163)] fn Callfiii() { todo!(); }, #[code(0x170)] fn Mzero() { todo!(); }, #[code(0x171)] fn Mcopy() { todo!(); }, #[code(0x178)] fn Malloc() { todo!(); }, #[code(0x179)] fn Mfree() { todo!(); }, #[code(0x180)] fn Accelfunc() { todo!(); }, #[code(0x181)] fn Accelparam() { todo!(); }, #[code(0x190)] fn Numtof() { todo!(); }, #[code(0x191)] fn Ftonumz() { todo!(); }, #[code(0x192)] fn Ftonumn() { todo!(); }, #[code(0x198)] fn Ceil() { todo!(); }, #[code(0x199)] fn Floor() { todo!(); }, #[code(0x1A0)] fn Fadd() { todo!(); }, #[code(0x1A1)] fn Fsub() { todo!(); }, #[code(0x1A2)] fn Fmul() { todo!(); }, #[code(0x1A3)] fn Fdiv() { todo!(); }, #[code(0x1A4)] fn Fmod() { todo!(); }, #[code(0x1A8)] fn Sqrt() { todo!(); }, #[code(0x1A9)] fn Exp() { todo!(); }, #[code(0x1AA)] fn Log() { todo!(); }, #[code(0x1AB)] fn Pow() { todo!(); }, #[code(0x1B0)] fn Sin() { todo!(); }, #[code(0x1B1)] fn Cos() { todo!(); }, #[code(0x1B2)] fn Tan() { todo!(); }, #[code(0x1B3)] fn Asin() { todo!(); }, #[code(0x1B4)] fn Acos() { todo!(); }, #[code(0x1B5)] fn Atan() { todo!(); }, #[code(0x1B6)] fn Atan2() { todo!(); }, #[code(0x1C0)] fn Jfeq() { todo!(); }, #[code(0x1C1)] fn Jfne() { todo!(); }, #[code(0x1C2)] fn Jflt() { todo!(); }, #[code(0x1C3)] fn Jfle() { todo!(); }, #[code(0x1C4)] fn Jfgt() { todo!(); }, #[code(0x1C5)] fn Jfge() { todo!(); }, #[code(0x1C8)] fn Jisnan() { todo!(); }, #[code(0x1C9)] fn Jisinf() { todo!(); }, #[code(0x200)] fn Numtod() { todo!(); }, #[code(0x201)] fn Dtonumz() { todo!(); }, #[code(0x202)] fn Dtonumn() { todo!(); }, #[code(0x203)] fn Ftod() { todo!(); }, #[code(0x204)] fn Dtof() { todo!(); }, #[code(0x208)] fn Dceil() { todo!(); }, #[code(0x209)] fn Dfloor() { todo!(); }, #[code(0x210)] fn Dadd() { todo!(); }, #[code(0x211)] fn Dsub() { todo!(); }, #[code(0x212)] fn Dmul() { todo!(); }, #[code(0x213)] fn Ddiv() { todo!(); }, #[code(0x214)] fn Dmodr() { todo!(); }, #[code(0x215)] fn Dmodq() { todo!(); }, #[code(0x218)] fn Dsqrt() { todo!(); }, #[code(0x219)] fn Dexp() { todo!(); }, #[code(0x21A)] fn Dlog() { todo!(); }, #[code(0x21B)] fn Dpow() { todo!(); }, #[code(0x220)] fn Dsin() { todo!(); }, #[code(0x221)] fn Dcos() { todo!(); }, #[code(0x222)] fn Dtan() { todo!(); }, #[code(0x223)] fn Dasin() { todo!(); }, #[code(0x224)] fn Dacos() { todo!(); }, #[code(0x225)] fn Datan() { todo!(); }, #[code(0x226)] fn Datan2() { todo!(); }, #[code(0x230)] fn Jdeq() { todo!(); }, #[code(0x231)] fn Jdne() { todo!(); }, #[code(0x232)] fn Jdlt() { todo!(); }, #[code(0x233)] fn Jdle() { todo!(); }, #[code(0x234)] fn Jdgt() { todo!(); }, #[code(0x235)] fn Jdge() { todo!(); }, #[code(0x238)] fn Jdisnan() { todo!(); }, #[code(0x239)] fn Jdisinf() { todo!(); } } );