Updating to reflect the latest work.
[zilutils.git] / zilasm / opcodes.c
diff --git a/zilasm/opcodes.c b/zilasm/opcodes.c
new file mode 100644 (file)
index 0000000..5478891
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ * opcodes.c -- part of ZilUtils/ZilAsm
+ *
+ * Copyright (C) 2016 Jason Self <j@jxself.org>
+ *
+ * Based on ZILF (c) 2010, 2015 Jesse McGrew
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+#include <assert.h>
+
+#include "opcodes.h"
+
+typedef struct {
+       unsigned opcode;
+       const char *classic_name;
+       const char *inform_name;
+       int minver;
+       int maxver;
+       ZOpcode_flags flags;
+} Opcode_detailed_info;
+
+static Opcode_detailed_info detailed_opcodes[] = {
+       { 20,  "ADD",         "add",             1, 6, Zop_store   },              // Add
+       { 259, "ASHIFT",      "art_shift",       5, 6, Zop_store   },              // Ashift
+       { 255, "ASSIGNED?",   "check_arg_count", 5, 6, Zop_branch | Zop_indvar },  // Assigned_P
+       { 9,   "BAND",        "and",             1, 6, Zop_store   },              // Band
+       { 143, "BCOM",        "not",             1, 4, Zop_store   },              // Bcom_V1
+       { 248, "BCOM",        "not",             5, 6, Zop_store   },              // Bcom_V5
+       { 8,   "BOR",         "or",              1, 6, Zop_store   },              // Bor
+       { 7,   "BTST",        "test",            1, 6, Zop_branch  },              // Btst
+       { 242, "BUFOUT",      "buffer_mode",     4, 6, 0           },              // Bufout
+       { 224, "CALL",        "call_vs",         1, 6, Zop_store | Zop_call },     // Call
+       { 136, "CALL1",       "call_1s",         4, 6, Zop_store | Zop_call },     // Call1
+       { 25,  "CALL2",       "call_2s",         4, 6, Zop_store | Zop_call },     // Call2
+       { 185, "CATCH",       "catch",           5, 6, Zop_store   },              // Catch
+       { 268, "CHECKU",      "check_unicode",   5, 6, Zop_store   },              // Checku
+       { 237, "CLEAR",       "erase_window",    4, 6, 0           },              // Clear
+       { 27,  "COLOR",       "set_colour",      5, 5, 0           },              // Color_v5
+       { 27,  "COLOR",       "set_colour",      6, 6, Zop_varargs },              // Color_v6
+       { 253, "COPYT",       "copy_table",      5, 6, 0           },              // Copyt
+       { 187, "CRLF",        "new_line",        1, 6, 0           },              // Crlf
+       { 240, "CURGET",      "get_cursor",      4, 6, 0           },              // Curget
+       { 239, "CURSET",      "set_cursor",      4, 6, 0           },              // Curset
+       { 263, "DCLEAR",      "erase_picture",   6, 6, 0           },              // Dclear
+       { 134, "DEC",         "dec",             1, 6, Zop_indvar  },              // Dec
+       { 244, "DIRIN",       "input_stream",    3, 6, 0           },              // Dir-In
+       { 243, "DIROUT",      "output_stream",   3, 6, 0           },              // Dir-Out
+       { 261, "DISPLAY",     "draw_picture",    6, 6, 0           },              // Display
+       { 23,  "DIV",         "div",             1, 6, Zop_store   },              // Div
+       { 4,   "DLESS?",      "dec_chk",         1, 6, Zop_branch | Zop_indvar },  // Dless_P
+//     { 271, "ENDMOVE",     "ENDMOVE",         5, 6, Zop_store   },              // Endmove = 271
+       { 1,   "EQUAL?",      "jeq",             1, 6, Zop_branch | Zop_varargs }, // Equal_P
+       { 238, "ERASE",       "erase_line",      4, 6, 0           },              // Erase
+       { 12,  "FCLEAR",      "clear_attr",      1, 6, 0           },              // Fclear
+       { 130, "FIRST?",      "get_child",       1, 6, Zop_store | Zop_branch },   // First_P
+       { 260, "FONT",        "set_font",        5, 6, Zop_store   },              // Font
+       { 11,  "FSET",        "set_attr",        1, 6, 0           },              // Fset
+       { 10,  "FSET?",       "test_attr",       1, 6, Zop_branch  },              // Fset_P
+       { 185, "FSTACK",      "pop",             1, 4, 0           },              // Fstack_V1
+       { 277, "FSTACK",      "pop_stack",       6, 6, 0           },              // Fstack_V6
+       { 15,  "GET",         "loadw",           1, 6, Zop_store   },              // Get
+       { 16,  "GETB",        "loadb",           1, 6, Zop_store   },              // Getb
+       { 17,  "GETP",        "get_prop",        1, 6, Zop_store   },              // Getp
+       { 18,  "GETPT",       "get_prop_addr",   1, 6, Zop_store   },              // Getpt
+       { 3,   "GRTR?",       "jg",              1, 6, Zop_branch  },              // Grtr_P
+       { 241, "HLIGHT",      "set_text_style",  4, 6, 0           },              // Hlight
+       { 249, "ICALL",       "call_vn",         5, 6, Zop_call    },              // Icall
+       { 143, "ICALL1",      "call_1n",         5, 6, Zop_call    },              // Icall1
+       { 26,  "ICALL2",      "call_2n",         5, 6, Zop_call    },              // Icall2
+       { 5,   "IGRTR?",      "inc_chk",         1, 6, Zop_branch | Zop_indvar },  // Igrtr_P
+       { 6,   "IN?",         "jin",             1, 6, Zop_branch  },              // In_P
+       { 133, "INC",         "inc",             1, 6, Zop_indvar  },              // Inc
+       { 246, "INPUT",       "read_char",       4, 6, Zop_store   },              // Input
+       { 247, "INTBL?",      "scan_table",      4, 6, Zop_store | Zop_branch },   // Intbl_P
+       { 266, "IRESTORE",    "restore_undo",    5, 6, Zop_store   },              // Irestore
+       { 265, "ISAVE",       "save_undo",       5, 6, Zop_store   },              // Isave
+       { 250, "IXCALL",      "call_vn2",        5, 6, Zop_extra | Zop_call },     // Ixcall
+       { 140, "JUMP",        "jump",            1, 6, Zop_label | Zop_term },     // Jump
+       { 2,   "LESS?",       "jl",              1, 6, Zop_branch  },              // Less_P
+       { 251, "LEX",         "tokenise",        5, 6, 0           },              // Lex
+       { 131, "LOC",         "get_parent",      1, 6, Zop_store   },              // Loc
+       { 264, "MARGIN",      "set_margins",     6, 6, 0           },              // Margin
+       { 283, "MENU",        "make_menu",       6, 6, Zop_branch  },              // Menu
+       { 24,  "MOD",         "mod",             1, 6, Zop_store   },              // Mod
+       { 278, "MOUSE-INFO",  "read_mouse",      6, 6, 0           },              // MouseInfo
+       { 279, "MOUSE-LIMIT", "mouse_window",    6, 6, 0           },              // MouseLimit
+       { 14,  "MOVE",        "insert_obj",      1, 6, 0           },              // Move
+       { 22,  "MUL",         "mul",             1, 6, Zop_store   },              // Mul
+       { 129, "NEXT?",       "get_sibling",     1, 6, Zop_store | Zop_branch },   // Next_P
+       { 19,  "NEXTP",       "get_next_prop",   1, 6, Zop_store   },              // Nextp
+       { 180, "NOOP",        "nop",             1, 6, 0           },              // Noop
+       { 191, "ORIGINAL?",   "piracy",          5, 6, Zop_branch  },              // Original_P
+       { 262, "PICINF",      "picture_data",    6, 6, Zop_branch  },              // Picinf
+       { 284, "PICSET",      "picture_table",   6, 6, 0           },              // Picset
+       { 233, "POP",         "pull",            1, 5, 0           },              // Pop_v1
+       { 233, "POP",         "pull",            6, 6, Zop_store   },              // Pop_v6
+       { 141, "PRINT",       "print_paddr",     1, 6, 0           },              // Print
+       { 135, "PRINTB",      "print_addr",      1, 6, 0           },              // Printb
+       { 229, "PRINTC",      "print_char",      1, 6, 0           },              // Printc
+       { 138, "PRINTD",      "print_obj",       1, 6, 0           },              // Printd
+       { 282, "PRINTF",      "print_form",      6, 6, 0           },              // Printf
+       { 178, "PRINTI",      "print",           1, 6, Zop_string  },              // Printi
+//     { 267, "PRINTMOVE",   "PRINTMOVE",       5, 6, Zop_store   },              // Printmove
+       { 230, "PRINTN",      "print_num",       1, 6, 0           },              // Printn
+       { 179, "PRINTR",      "print_ret",       1, 6, Zop_string | Zop_term },    // Printr
+       { 254, "PRINTT",      "print_table",     5, 6, 0           },              // Printt
+       { 267, "PRINTU",      "print_unicode",   5, 6, 0           },              // Printu
+       { 132, "PTSIZE",      "get_prop_len",    1, 6, Zop_store   },              // Ptsize
+       { 232, "PUSH",        "push",            1, 6, 0           },              // Push
+       { 225, "PUT",         "storew",          1, 6, 0           },              // Put
+       { 226, "PUTB",        "storeb",          1, 6, 0           },              // Putb
+       { 227, "PUTP",        "put_prop",        1, 6, 0           },              // Putp
+       { 186, "QUIT",        "quit",            1, 6, Zop_term    },              // Quit
+       { 231, "RANDOM",      "random",          1, 6, Zop_store   },              // Random
+       { 228, "READ",        "sread",           1, 4, 0           },              // Read_v1
+       { 228, "READ",        "aread",           5, 6, Zop_store   },              // Read_v5
+       { 137, "REMOVE",      "remove_obj",      1, 6, 0           },              // Remove
+       { 183, "RESTART",     "restart",         1, 6, Zop_term    },              // Restart
+       { 182, "RESTORE",     "restore",         1, 3, Zop_branch  },              // Restore_v1
+       { 182, "RESTORE",     "restore",         4, 4, Zop_store   },              // Restore_v4
+       { 257, "RESTORE",     "restore",         5, 6, Zop_store   },              // Restore_V5
+       { 139, "RETURN",      "ret",             1, 6, Zop_term    },              // Return
+       { 177, "RFALSE",      "rfalse",          1, 6, Zop_term    },              // Rfalse
+       { 184, "RSTACK",      "ret_popped",      1, 6, Zop_term    },              // Rstack
+//     { 268, "RTIME",       "RTIME",           5, 6, Zop_store   },              // Rtime
+       { 176, "RTRUE",       "rtrue",           1, 6, Zop_term    },              // Rtrue
+       { 181, "SAVE",        "save",            1, 3, Zop_branch  },              // Save_v1
+       { 181, "SAVE",        "save",            4, 4, Zop_store   },              // Save_v4
+       { 256, "SAVE",        "save",            5, 6, Zop_store   },              // Save_V5
+       { 235, "SCREEN",      "set_window",      3, 6, 0           },              // Screen
+       { 276, "SCROLL",      "scroll_window",   6, 6, 0           },              // Scroll
+//     { 269, "SEND",        "SEND",            5, 6, Zop_store   },              // Send
+       { 270, "SERVER",      "SERVER",          5, 6, Zop_store   },              // Server
+       { 13,  "SET",         "store",           1, 6, Zop_indvar  },              // Set
+       { 258, "SHIFT",       "log_shift",       5, 6, Zop_store   },              // Shift
+       { 245, "SOUND",       "sound_effect",    3, 6, 0           },              // Sound
+       { 234, "SPLIT",       "split_window",    3, 6, 0           },              // Split
+       { 21,  "SUB",         "sub",             1, 6, Zop_store   },              // Sub
+       { 28,  "THROW",       "throw",           5, 6, Zop_term    },              // Throw
+       { 188, "USL",         "show_status",     1, 3, 0           },              // Usl
+       { 142, "VALUE",       "load",            1, 6, Zop_store | Zop_indvar },   // Value
+       { 189, "VERIFY",      "verify",          3, 6, Zop_branch  },              // Verify
+       { 274, "WINATTR",     "window_style",    6, 6, 0           },              // Winattr
+       { 275, "WINGET",      "get_wind_prop",   6, 6, Zop_store   },              // Winget
+       { 272, "WINPOS",      "move_window",     6, 6, 0           },              // Winpos
+       { 281, "WINPUT",      "put_wind_prop",   6, 6, 0           },              // Winput
+       { 273, "WINSIZE",     "window_size",     6, 6, 0           },              // Winsize
+       { 236, "XCALL",       "call_vs2",        4, 6, Zop_store | Zop_extra | Zop_call }, // Xcall
+       { 280, "XPUSH",       "push_stack",      6, 6, Zop_branch  },              // Xpush
+       { 128, "ZERO?",       "jz",              1, 6, Zop_branch  },              // Zero_P
+       { 252, "ZWSTR",       "encode_text",     5, 6, 0           }               // Zwstr
+};
+
+Symtable *Opcodes;
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+
+void init_opcodes(int version, int inform_syntax)
+{
+       const unsigned maxnamelen = 16;
+       int n;
+       if (Opcodes) symtable_destroy(Opcodes); 
+       Opcodes = symtable_create(2 * ARRAY_SIZE(detailed_opcodes), maxnamelen, sizeof(ZOpcode));
+       assert(Opcodes);
+       for(n = 0; n < ARRAY_SIZE(detailed_opcodes); n++) {
+               Opcode_detailed_info *p = &detailed_opcodes[n];
+               if (version < p->minver) continue;
+               if (version > p->maxver) continue;
+               ZOpcode q = { p->opcode, p->flags };
+               symtable_add(Opcodes, inform_syntax ? p->inform_name : p->classic_name, &q);
+       }
+}