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