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