configure fixes, N900 fixes
[awish.git] / tools / disasm.bob
blob3331d7b4e2eac52793ebea03cf482c3648df9b4c
1 #!/usr/bin/bob
2 /* coded by Ketmar // Vampire Avalon (psyc://ketmar.no-ip.org/~Ketmar)
3  * Understanding is not required. Only obedience.
4  *
5  * This program is free software. It comes without any warranty, to
6  * the extent permitted by applicable law. You can redistribute it
7  * and/or modify it under the terms of the Do What The Fuck You Want
8  * To Public License, Version 2, as published by Sam Hocevar. See
9  * http://sam.zoy.org/wtfpl/COPYING for more details. */
12 define abort (msg) {
13   writeln("ERROR: ", msg);
14   quit(1);
18 LB_GVAR = 0;
19 LB_TVAR = 1;
20 LB_SVAR = 2;
21 LB_CODE = 3;
22 LB_CONST = 4;
25 opnames = \[
26   "add",
27   "sub",
28   "mul",
29   "div",
30   "mod",
31   "bor",
32   "xor",
33   "and",
35   "jeq",
36   "jne",
37   "jlt",
38   "jle",
39   "jgt",
40   "jge",
42   "jmp",
44   "bsr",
46   "brk",
47   "end",
48   "new",
50   "set",
51   "get",
53   "psh",
54   "pop",
55   "swp",
56   "pck",
57   "rol",
58   "dpt",
60   "tid",
61   "kil",
62   "sus",
63   "res",
64   "sta",
66   "rxc",
67   "wxc",
69   "ret",
71   "rst",
73   "mgf",
74   "mgb",
75   "msf",
76   "msb",
80 define isBranch (mnemo) {
81   switch (mnemo) {
82     case "jmp":
83     case "bsr":
84     case "jeq":
85     case "jne":
86     case "jlt":
87     case "jle":
88     case "jgt":
89     case "jge":
90       return true;
91   }
92   return false;
96 fl = new File(args.length<1?"awish.vmd":args[0], "rb");
97 if (!fl) abort("no code file");
98 sign = fl.readBuf(4);
99 if (sign != "AVM2") abort("invalid code file");
100 csize = fl.readWord()^0x2a2a; // code size
101 rcnt = fl.readWord()^0x2a2a; // number of fixups
102 elcnt = fl.readWord()^0x2a2a; // number of extern labels
103 lcnt = fl.readWord()^0x2a2a; // number of labels
104 gvmax = fl.readWord()^0x2a2a; // number of global vars
105 tvmax = fl.readWord()^0x2a2a; // number of thread local vars
106 writeln("code: %d bytes, %d public labels, %d relocations, %d externs".format(csize, lcnt, rcnt, elcnt));
107 code = fl.readBuf(csize);
108 for (local f = 0; f < code.length; ++f) code[f] ^= 0x2a;
110 for (local f = 0; f < rcnt; ++f) {
111   local pc = fl.readWord()^0x2a2a;
112   writeln("0x%04x".format(pc));
115 fl.close();
118 define findLabel (val, type) {
119   /*
120   foreach (local l with list.items()) {
121     if (l.type == type && l.value == val) return l.name;
122   }
123   */
124   return nil;
128 pc = 0;
129 while (pc < code.length) {
130   local opcode = code[pc++], argc, brn, name;
131   //
132   argc = (opcode>>6)&0x03;
133   opcode &= 0x3f;
134   if (opcode >= opnames.length) {
135     write("%04x: BAD".format(pc-1));
136     name = "BAD";
137   } else if (opnames[opcode] == "jmp" && argc == 0) {
138     write("%04x: %s".format(pc-1, "ret"));
139     name = opnames[opcode];
140   } else {
141     write("%04x: %s".format(pc-1, opnames[opcode]));
142     name = opnames[opcode];
143   }
144   brn = isBranch(name);
145   // read operands
146   for (local f = 0; f < argc; ++f) {
147     local vn = code[pc++], val, var = 0, name;
148     //
149     if (f != 0) write(", "); else write(" ");
150     if (vn == 255) {
151       // immediate
152       val = code[pc++];
153       val |= (code[pc++]<<8);
154       if ((f != 00 || !brn) && val >= 32768) val -= 65536;
155       if (brn && f == 0) {
156         name = findLabel(val, LB_CODE);
157         if (name) write(name); else write("0x%04x".format(val));
158       } else {
159         //name = findLabel(val, LB_CONST);
160         name = nil;
161         if (name) write(name); else write(val);
162       }
163     } else if (vn == 127) {
164       // stack
165       val = code[pc++];
166       val |= (code[pc++]<<8);
167       if (val >= 32768) val -= 65536;
168       write("[.", val, "]");
169     } else {
170       // variable
171       if (vn >= 0x80) {
172         // global
173         var = 1;
174         val = vn&0x7f;
175         name = findLabel(val, LB_GVAR);
176         if (name) write("[", name, "]"); else write("[@", val, "]");
177       } else {
178         // thread
179         var = 2;
180         val = vn&0x7f;
181         name = findLabel(val, LB_TVAR);
182         if (name) write("[", name, "]"); else write("[", val, "]");
183       }
184     }
185   }
186   writeln();