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