shithub: pokecrystal

Download patch

ref: 651d8017342e9bbd9f491d8df4c84a84e86a3ee4
parent: a4b19fe60ad2044ec1eb3f51e912782dd25adba9
author: Bryan Bishop <[email protected]>
date: Sun Mar 25 09:53:21 EDT 2012

refactor script parsing into a Script class

--- a/extras/crystal.py
+++ b/extras/crystal.py
@@ -1144,7 +1144,7 @@
     #TODO: recursively follow any jumps in the script
     if script == None: return []
     addresses = set()
-    for (k, command) in script.items():
+    for (k, command) in script.commands.items():
         if debug:
             print "command is: " + str(command)
         if   command["type"] == 0x4B:
@@ -1520,1833 +1520,1921 @@
                0x9f58f, #battle tower
                0x9f62f, #battle tower
               ]
-def parse_script_engine_script_at(address, map_group=None, map_id=None, force=False, debug=True, origin=False):
-    """parses a script-engine script
-    force=True if you want to re-parse and get the debug information"""
-    global rom
-    if rom == None:
-        load_rom()
+class Script():
+    def __init__(self, *args, **kwargs):
+        self.address = None
+        self.commands = None
+        if len(kwargs) == 0 and len(args) == 0:
+            raise Exception, "Script.__init__ must be given some arguments"
+        #first positional argument is address
+        if len(args) == 1:
+            address = args[0]
+            if type(address) == str:
+                address = int(address, 16)
+            elif type(address) != int:
+                raise Exception, "address must be an integer or string"
+            self.address = address
+        elif len(args) > 1:
+            raise Exception, "don't know what to do with second (or later) positional arguments"
+        #parse the script at the address
+        self.parse(**kwargs)
+    def pksv_list(self):
+        """shows a list of pksv names for each command in the script"""
+        items = []
+        for (id, command) in self.commands.items():
+            if command["type"] in pksv_crystal:
+                items.append(pksv_crystal[command["type"]])
+            else:
+                items.append(hex(command["type"]))
+        return items
+    def to_pksv(self):
+        """returns a string of pksv command names"""
+        pksv = self.pksv_list()
+        output = "script starting at: "+hex(self.address)+" .. "
+        first = True
+        for item in pksv:
+            item = str(item)
+            if first:
+                output += item
+                first = False
+            else:
+                output += ", "+item
+        return output
+    def show_pksv(self):
+        """prints a list of pksv command names in this script"""
+        print self.to_pksv()
+    def parse(self, *args, **kwargs):
+        """parses a script-engine script; force=True if you want to re-parse
+        and get the debug information"""
+        #can't handle more than one argument
+        if len(args) > 1:
+            raise Exception, "Script.parse_script doesn't know how to handle positional arguments"
+        #use the first positional argument as the address
+        elif len(args) == 1:
+            self.address = args[0]
+            if type(self.address) == str:
+                self.address = int(self.address, 16)
+            elif type(self.address) != int:
+                raise Exception, "address param is the wrong type"
+        #parse any keyword arguments, first make up the defaults
+        kwargsorig = {"map_group": None, "map_id": None, "force": False, "debug": True, "origin": False}
+        #let the caller override any defaults
+        kwargsorig.update(kwargs)
+        #copy these into kwargs
+        kwargs = kwargsorig
+        #set these defaults
+        map_group = kwargs["map_group"]
+        map_id = kwargs["map_id"]
+        force = kwargs["force"]
+        debug = kwargs["debug"]
+        origin = kwargs["origin"]
+        self.map_group = map_group
+        self.map_id = map_id
     
-    if address in stop_points:
-        print "got " + hex(address) + ".. map_group=" + str(map_group) + " map_id=" + str(map_id)
-        return {}
-    if address < 0x4000 and address not in [0x26ef, 0x114, 0x1108]:
-        print "address is less than 0x4000.. address is: " + hex(address)
-        sys.exit()
+        global rom
+        if rom == None:
+            load_rom()
+        
+        #max number of commands in a 'recursive' script
+        max_cmds = 150
     
-    #max number of commands in a 'recursive' script
-    max_cmds = 150
-
-    #check if work is being repeated
-    if is_script_already_parsed_at(address) and not force:
-        return script_parse_table[address]
-    original_start_address = address
-    #this next line stops the same script from being re-parsed multiple times
-    #for instance.. maybe there's a script jump, then a jump back
-    #the original script should only be parsed once
-    script_parse_table[original_start_address:original_start_address+1] = "incomplete"
-    #set up some variables
-    commands = {}
-    offset = address
-    end = False
-    #main loop.. parse each command byte
-    while not end:
-        #reset variables so we don't contaminate this command
-        info, long_info, size = None, None, 0
-        #read the current command byte
-        command_byte = ord(rom[offset])
-        #setup the current command representation
-        command = {"type": command_byte, "start_address": offset}
-
-        #size is the total size including the command byte
-        #last_byte_address is offset+size-1
-        start_address = offset
-
-        if (len(commands.keys()) > max_cmds) and origin != False:
-            print "too many commands in this script? might not be a script (starting at: " +\
-                  hex(original_start_address) + ").. called from a script at: " + hex(origin)
+        #set the address to be parsed
+        address = self.address
+        original_start_address = address
+    
+        #don't parse these crazy things (battle tower things, some rival things, etc.)
+        if address in stop_points:
+            print "got " + hex(address) + ".. map_group=" + str(map_group) + " map_id=" + str(map_id)
+            return None
+        #don't parse anything that looks crazy
+        if address < 0x4000 and address not in [0x26ef, 0x114, 0x1108]:
+            print "address is less than 0x4000.. address is: " + hex(address)
             sys.exit()
-
-        #start checking against possible command bytes
-        if   command_byte == 0x00: #Pointer code [2b+ret]
-            pksv_name = "2call"
-            info = "pointer code"
-            long_info = """
-            2byte pointer points to script; when pointed script ends --> return to old script
-            [code][2 byte pointer]
-            """
-            size = 3
+    
+        #check if work is being repeated
+        if is_script_already_parsed_at(address) and not force:
+            raise Exception, "this script has already been parsed before, please use that instance"
+            #use the commands from a previously-parsed Script object
+            #self.commands = script_parse_table[address].commands
+            #return True
+            
+            #return a previously-created Script object
+            #return script_parse_table[address]
+        
+        #this next line stops the same script from being re-parsed multiple times
+        #for instance.. maybe there's a script jump, then a jump back
+        #the original script should only be parsed once
+        script_parse_table[original_start_address:original_start_address+1] = "incomplete"
+        
+        #set up some variables
+        self.commands = {}
+        commands = self.commands
+        offset = address
+        end = False
+    
+        #main loop.. parse each command byte
+        while not end:
+            #reset variables so we don't contaminate this command
+            info, long_info, size = None, None, 0
+            #read the current command byte
+            command_byte = ord(rom[offset])
+            #setup the current command representation
+            command = {"type": command_byte, "start_address": offset}
+    
+            #size is the total size including the command byte
+            #last_byte_address is offset+size-1
             start_address = offset
-            last_byte_address = offset + size - 1
-            pointer = calculate_pointer_from_bytes_at(start_address+1)
-            command["pointer"] = pointer
-            if debug:
-                print "in script starting at "+hex(original_start_address)+\
+    
+            if (len(commands.keys()) > max_cmds) and origin != False:
+                print "too many commands in this script? might not be a script (starting at: " +\
+                      hex(original_start_address) + ").. called from a script at: " + hex(origin)
+                sys.exit()
+    
+            #start checking against possible command bytes
+            if   command_byte == 0x00: #Pointer code [2b+ret]
+                pksv_name = "2call"
+                info = "pointer code"
+                long_info = """
+                2byte pointer points to script; when pointed script ends --> return to old script
+                [code][2 byte pointer]
+                """
+                size = 3
+                start_address = offset
+                last_byte_address = offset + size - 1
+                pointer = calculate_pointer_from_bytes_at(start_address+1)
+                command["pointer"] = pointer
+                if debug:
+                    print "in script starting at "+hex(original_start_address)+\
+                          " about to parse script at "+hex(pointer)+\
+                          " called by "+info+" byte="+hex(command_byte)
+                script = rec_parse_script_engine_script_at(pointer, original_start_address, debug=debug)
+                command["script"] = script
+            elif command_byte == 0x01: #Pointer code [3b+ret]
+                pksv_name = "3call"
+                info = "pointer code"
+                long_info = """
+                3byte pointer points to script; when pointed script ends --> return to old script
+                [Code][resp. pointer(2byte or 3byte)]
+                """
+                size = 4
+                info = "pointer code"
+                pointer = calculate_pointer_from_bytes_at(start_address+1, bank=True)
+                if debug:
+                    print "in script starting at "+hex(original_start_address)+\
+                          " about to parse script at "+hex(pointer)+\
+                          " called by "+info+" byte="+hex(command_byte)
+                script = rec_parse_script_engine_script_at(pointer, original_start_address, debug)
+                command["pointer"] = pointer
+                command["script"] = script
+            elif command_byte == 0x02: #Pointer code [2b+3b+ret]
+                info = "pointer code"
+                long_info = """
+                2byte pointer points to 3byte pointer; when pointed script --> return to old script
+                [Code][resp. pointer(2byte or 3byte)]
+                """
+                size = 3
+                pointer = calculate_pointer_from_bytes_at(start_address+1)
+                if debug:
+                    print "in script starting at "+hex(original_start_address)+\
+                          " about to parse script at "+hex(pointer)+\
+                          " called by "+info+" byte="+hex(command_byte)
+                script = rec_parse_script_engine_script_at(pointer, original_start_address, debug=debug)
+                command["pointer"] = pointer
+                command["script"] = script
+            elif command_byte == 0x03: #Pointer code [2b]
+                #XXX what does "new script is part of main script" mean?
+                info = "pointer code"
+                long_info = """
+                2byte pointer points to script; new script is part of main script
+                [Code][resp. pointer(2byte or 3byte)]
+                """
+                size = 3
+                pointer = calculate_pointer_from_bytes_at(start_address+1)
+                if debug:
+                    print "in script starting at "+hex(original_start_address)+\
+                          " about to parse script at "+hex(pointer)+\
+                          " called by "+info+" byte="+hex(command_byte)
+                script = rec_parse_script_engine_script_at(pointer, original_start_address, debug=debug)
+                command["pointer"] = pointer
+                command["script"] = script
+                end = True #according to pksv
+            elif command_byte == 0x04: #Pointer code [3b]
+                info = "pointer code"
+                long_info = """
+                3byte pointer points to script; new script is part of main script
+                [Code][resp. pointer(2byte or 3byte)]
+                """
+                size = 4
+                pointer = calculate_pointer_from_bytes_at(start_address+1, bank=True)
+                if debug:
+                    print "in script starting at "+hex(original_start_address)+\
                       " about to parse script at "+hex(pointer)+\
                       " called by "+info+" byte="+hex(command_byte)
-            script = rec_parse_script_engine_script_at(pointer, original_start_address, debug=debug)
-            command["script"] = script
-        elif command_byte == 0x01: #Pointer code [3b+ret]
-            pksv_name = "3call"
-            info = "pointer code"
-            long_info = """
-            3byte pointer points to script; when pointed script ends --> return to old script
-            [Code][resp. pointer(2byte or 3byte)]
-            """
-            size = 4
-            info = "pointer code"
-            pointer = calculate_pointer_from_bytes_at(start_address+1, bank=True)
-            if debug:
-                print "in script starting at "+hex(original_start_address)+\
+                script = rec_parse_script_engine_script_at(pointer, original_start_address, debug=debug)
+                command["pointer"] = pointer
+                command["script"] = script
+                end = True #according to pksv
+            elif command_byte == 0x05: #Pointer code [2b+3b]
+                info = "pointer code"
+                long_info = """
+                2byte pointer points to 3byte pointer; new script is part of main script
+                [Code][resp. pointer(2byte or 3byte)]
+                """
+                size = 3
+                command["pointer"] = calculate_pointer_from_bytes_at(start_address+1)
+                command["target_pointer"] = calculate_pointer_from_bytes_at(command["pointer"], bank=True)
+                
+                if debug:
+                    print "in script starting at "+hex(original_start_address)+\
+                      " about to parse script at "+hex(command["target_pointer"])+\
+                      " called by "+info+" byte="+hex(command_byte)
+                script = rec_parse_script_engine_script_at(command["target_pointer"], original_start_address, debug=debug)
+                command["script"] = script
+                end = True #according to pksv
+            elif command_byte == 0x06: #RAM check [=byte]
+                info = "RAM check [=byte]"
+                long_info = """
+                When the conditional is true...
+                .. then go to pointed script, else resume interpreting after the pointer
+                """
+                size = 4
+                command["byte"] = ord(rom[start_address+1])
+                pointer = calculate_pointer_from_bytes_at(start_address+2)
+                if debug:
+                    print "in script starting at "+hex(original_start_address)+\
                       " about to parse script at "+hex(pointer)+\
                       " called by "+info+" byte="+hex(command_byte)
-            script = rec_parse_script_engine_script_at(pointer, original_start_address, debug)
-            command["pointer"] = pointer
-            command["script"] = script
-        elif command_byte == 0x02: #Pointer code [2b+3b+ret]
-            info = "pointer code"
-            long_info = """
-            2byte pointer points to 3byte pointer; when pointed script --> return to old script
-            [Code][resp. pointer(2byte or 3byte)]
-            """
-            size = 3
-            pointer = calculate_pointer_from_bytes_at(start_address+1)
-            if debug:
-                print "in script starting at "+hex(original_start_address)+\
+                script = rec_parse_script_engine_script_at(pointer, original_start_address, debug=debug)
+                command["pointer"] = pointer
+                command["script"] = script
+            elif command_byte == 0x07: #RAM check [<>byte]
+                info = "RAM check [<>byte]"
+                long_info = """
+                When the conditional is true...
+                .. then go to pointed script, else resume interpreting after the pointer
+                """
+                size = 4
+                command["byte"] = ord(rom[start_address+1])
+                pointer = calculate_pointer_from_bytes_at(start_address+2)
+                if debug:
+                    print "in script starting at "+hex(original_start_address)+\
                       " about to parse script at "+hex(pointer)+\
                       " called by "+info+" byte="+hex(command_byte)
-            script = rec_parse_script_engine_script_at(pointer, original_start_address, debug=debug)
-            command["pointer"] = pointer
-            command["script"] = script
-        elif command_byte == 0x03: #Pointer code [2b]
-            #XXX what does "new script is part of main script" mean?
-            info = "pointer code"
-            long_info = """
-            2byte pointer points to script; new script is part of main script
-            [Code][resp. pointer(2byte or 3byte)]
-            """
-            size = 3
-            pointer = calculate_pointer_from_bytes_at(start_address+1)
-            if debug:
-                print "in script starting at "+hex(original_start_address)+\
+                script = rec_parse_script_engine_script_at(pointer, original_start_address, debug=debug)
+                command["pointer"] = pointer
+                command["script"] = script
+            elif command_byte == 0x08: #RAM check [=0]
+                info = "RAM check [=0]"
+                long_info = """
+                When the conditional is true...
+                .. then go to pointed script, else resume interpreting after the pointer
+                """
+                size = 3
+                pointer = calculate_pointer_from_bytes_at(start_address+1)
+                if debug:
+                    print "in script starting at "+hex(original_start_address)+\
                       " about to parse script at "+hex(pointer)+\
                       " called by "+info+" byte="+hex(command_byte)
-            script = rec_parse_script_engine_script_at(pointer, original_start_address, debug=debug)
-            command["pointer"] = pointer
-            command["script"] = script
-            end = True #according to pksv
-        elif command_byte == 0x04: #Pointer code [3b]
-            info = "pointer code"
-            long_info = """
-            3byte pointer points to script; new script is part of main script
-            [Code][resp. pointer(2byte or 3byte)]
-            """
-            size = 4
-            pointer = calculate_pointer_from_bytes_at(start_address+1, bank=True)
-            if debug:
-                print "in script starting at "+hex(original_start_address)+\
-                  " about to parse script at "+hex(pointer)+\
-                  " called by "+info+" byte="+hex(command_byte)
-            script = rec_parse_script_engine_script_at(pointer, original_start_address, debug=debug)
-            command["pointer"] = pointer
-            command["script"] = script
-            end = True #according to pksv
-        elif command_byte == 0x05: #Pointer code [2b+3b]
-            info = "pointer code"
-            long_info = """
-            2byte pointer points to 3byte pointer; new script is part of main script
-            [Code][resp. pointer(2byte or 3byte)]
-            """
-            size = 3
-            command["pointer"] = calculate_pointer_from_bytes_at(start_address+1)
-            command["target_pointer"] = calculate_pointer_from_bytes_at(command["pointer"], bank=True)
-            
-            if debug:
-                print "in script starting at "+hex(original_start_address)+\
-                  " about to parse script at "+hex(command["target_pointer"])+\
-                  " called by "+info+" byte="+hex(command_byte)
-            script = rec_parse_script_engine_script_at(command["target_pointer"], original_start_address, debug=debug)
-            command["script"] = script
-            end = True #according to pksv
-        elif command_byte == 0x06: #RAM check [=byte]
-            info = "RAM check [=byte]"
-            long_info = """
-            When the conditional is true...
-            .. then go to pointed script, else resume interpreting after the pointer
-            """
-            size = 4
-            command["byte"] = ord(rom[start_address+1])
-            pointer = calculate_pointer_from_bytes_at(start_address+2)
-            if debug:
-                print "in script starting at "+hex(original_start_address)+\
-                  " about to parse script at "+hex(pointer)+\
-                  " called by "+info+" byte="+hex(command_byte)
-            script = rec_parse_script_engine_script_at(pointer, original_start_address, debug=debug)
-            command["pointer"] = pointer
-            command["script"] = script
-        elif command_byte == 0x07: #RAM check [<>byte]
-            info = "RAM check [<>byte]"
-            long_info = """
-            When the conditional is true...
-            .. then go to pointed script, else resume interpreting after the pointer
-            """
-            size = 4
-            command["byte"] = ord(rom[start_address+1])
-            pointer = calculate_pointer_from_bytes_at(start_address+2)
-            if debug:
-                print "in script starting at "+hex(original_start_address)+\
-                  " about to parse script at "+hex(pointer)+\
-                  " called by "+info+" byte="+hex(command_byte)
-            script = rec_parse_script_engine_script_at(pointer, original_start_address, debug=debug)
-            command["pointer"] = pointer
-            command["script"] = script
-        elif command_byte == 0x08: #RAM check [=0]
-            info = "RAM check [=0]"
-            long_info = """
-            When the conditional is true...
-            .. then go to pointed script, else resume interpreting after the pointer
-            """
-            size = 3
-            pointer = calculate_pointer_from_bytes_at(start_address+1)
-            if debug:
-                print "in script starting at "+hex(original_start_address)+\
-                  " about to parse script at "+hex(pointer)+\
-                  " called by "+info+" byte="+hex(command_byte)
-            script = rec_parse_script_engine_script_at(pointer, original_start_address, debug=debug)
-            command["pointer"] = pointer
-            command["script"] = script
-        elif command_byte == 0x09: #RAM check [<>0]
-            info = "RAM check [<>0]"
-            long_info = """
-            When the conditional is true...
-            .. then go to pointed script, else resume interpreting after the pointer
-            """
-            size = 3
-            pointer = calculate_pointer_from_bytes_at(start_address+1)
-            if debug:
-                print "in script starting at "+hex(original_start_address)+\
-                  " about to parse script at "+hex(pointer)+\
-                  " called by "+info+" byte="+hex(command_byte)
-            script = rec_parse_script_engine_script_at(pointer, original_start_address, debug=debug)
-            command["pointer"] = pointer
-            command["script"] = script
-        elif command_byte == 0x0A: #RAM check [<byte]
-            info = "RAM check [<byte]"
-            long_info = """
-            When the conditional is true...
-            .. then go to pointed script, else resume interpreting after the pointer
-            """
-            size = 4
-            command["byte"] = ord(rom[start_address+1])
-            pointer = calculate_pointer_from_bytes_at(start_address+2)
-            if debug:
-                print "in script starting at "+hex(original_start_address)+\
-                  " about to parse script at "+hex(pointer)+\
-                  " called by "+info+" byte="+hex(command_byte)
-            script = rec_parse_script_engine_script_at(pointer, original_start_address, debug=debug)
-            command["pointer"] = pointer
-            command["script"] = script
-        elif command_byte == 0x0B: #RAM check [>byte]
-            info = "RAM check [>byte]"
-            long_info = """
-            When the conditional is true...
-            .. then go to pointed script, else resume interpreting after the pointer
-            """
-            size = 4
-            command["byte"] = ord(rom[start_address+1])
-            pointer = calculate_pointer_from_bytes_at(start_address+2)
-            if debug:
-                print "in script starting at "+hex(original_start_address)+\
-                  " about to parse script at "+hex(pointer)+\
-                  " called by "+info+" byte="+hex(command_byte)
-            script = rec_parse_script_engine_script_at(pointer, original_start_address, debug=debug)
-            command["pointer"] = pointer
-            command["script"] = script
-        elif command_byte == 0x0C: #0C codes [xxyy]
-            info = "call predefined script then end"
-            long_info = """
-            Calls predefined scripts. After this code the script ends.
-            [0C][xxyy]
-            """
-            size = 3
-            end = True
-            byte1 = ord(rom[offset+1])
-            byte2 = ord(rom[offset+2])
-            number = byte1 + (byte2 << 8)
-            #0000 to 000AD ... XXX how should these be handled?
-            command["predefined_script_number"] = number
-        elif command_byte == 0x0D: #0D codes [xxyy]
-            info = "call some predefined script"
-            long_info = """
-            Calls predefined scripts. Exactly like $0C except the script does not end.
-            [0D][xxyy]
-            """
-            size = 3
-            byte1 = ord(rom[offset+1])
-            byte2 = ord(rom[offset+2])
-            number = byte1 + (byte2 << 8)
-            #0000 to 000AD ... XXX how should these be handled?
-            command["predefined_script_number"] = number
-        elif command_byte == 0x0E: #ASM code1 [3b]
-            info = "ASM code1 [3b]"
-            long_info = """
-            Calls a predefined routine by interpreting the ASM the pointer points to.
-            [0E][3byte pointer]
-            """
-            size = 4
-            command["pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=True)
-            #XXX should we dissassemble the asm at the target location?
-        elif command_byte == 0x0F: #0F codes [xxyy]
-            info = "call some predefined script [0F][yyxx]"
-            long_info = """
-            Calls predefined scripts.
-            [0F][yyxx]
-            NOTE: For (some) dialogues the font needs to be loaded with the Text box&font code.
-            """
-            size = 3
-            byte1 = ord(rom[offset+1])
-            byte2 = ord(rom[offset+2])
-            number = byte1 + (byte2 << 8)
-            command["predefined_script_number"] = number
-        elif command_byte == 0x10: #ASM code2 [2b]
-            info = "ASM code2 [2b to 3b to asm]"
-            long_info = """
-            Call an ASM script via a 2byte pointer pointing to a 3byte pointer.
-            [10][2byte pointer pointing to 3byte pointer pointing to ASM script]
-            """
-            size = 3
-            command["pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
-            #XXX should i include the 3-byte pointer at the target location?
-            #XXX should we dissassemble the asm at the target location?
-        elif command_byte == 0x11: #Trigger event check1 [xxyy]
-            info = "Trigger event check1 [xx][yy]"
-            long_info = """
-            Check the current number of the trigger event on map (map group/map id).
-            [11][map group][map number]
-            """
-            size = 3
-            command["map_group"] = ord(rom[start_address+1])
-            command["map_id"] = ord(rom[start_address+2])
-        elif command_byte == 0x12: #Activate trigger event from afar [xxyyzz]
-            info = "Activate trigger event from afar [xx][yy][zz]"
-            long_info = """
-            Changes trigger event number on map (map bank/map no) to xx.
-            xx = trigger event number that should be activated
-            [12][MapBank][MapNo][xx]
-            """
-            size = 4
-            command["map_group"] = ord(rom[start_address+1])
-            command["map_id"] = ord(rom[start_address+2])
-            command["trigger_number"] = ord(rom[start_address+3])
-        elif command_byte == 0x13: #Trigger event check
-            info = "Trigger event check"
-            long_info = """
-            Checks the number of the trigger events on the current map.
-            [13]
-            """
-            size = 1
-        elif command_byte == 0x14: #De-/activate trigger event [xx]
-            info = "De-/activate trigger event [xx]"
-            long_info = """
-            Changes trigger event number on current map to xx.
-            xx = trigger event number that should be activated
-            [14][xx]
-            deactivate? Just activate a different trigger event number. There's a limit of 1 active trigger.
-            """
-            size = 2
-            command["trigger_number"] = ord(rom[start_address+1])
-        elif command_byte == 0x15: #Load variable into RAM [xx]
-            info = "Load variable into RAM [xx]"
-            long_info = "[15][xx]"
-            size = 2
-            command["variable"] = ord(rom[start_address+1])
-        elif command_byte == 0x16: #Add variables [xx]
-            info = "Add variables [xx]"
-            long_info = """
-            Adds xx and the variable in RAM.
-            #[16][xx]
-            """
-            size = 2
-            command["variable"] = ord(rom[start_address+1])
-        elif command_byte == 0x17: #Random number [xx]
-            info = "Random number [xx]"
-            long_info = """
-            #Reads xx and creates a random number between 00 and xx -1.
-            #According to this xx can be all but 00. Random number = [00; xx)
-            #The nearer the random number is to xx, the rarer it occurs.
-            #Random number gets written to RAM.
-            """
-            size = 2
-            command["rarest"] = ord(rom[start_address+1])
-        elif command_byte == 0x18: #Version check
-            info = "G/S version check"
-            long_info = """
-            #Check if version is gold or silver. Gives feedback.
-            #00 = Gold
-            #01 = Silver
-            #[18]
-            """
-            size = 1
-        elif command_byte == 0x19: #Copy variable code1 [xxyy]
-            info = "Copy from RAM address to script RAM variable [xxyy]"
-            long_info = """
-            #Writes variable from ram address to RAM.
-            #[19][2-byte RAM address]
-            """
-            size = 3
-            #XXX maybe a pointer is a bad idea?
-            command["pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
-        elif command_byte == 0x1A: #Copy variable code2 [xxyy]
-            info = "Write variable from script RAM variable to actual RAM address [xxyy]"
-            long_info = """
-            #Writes variable from RAM to actual RAM address.
-            #[1A][2-byte RAM address]
-            """
-            size = 3
-            command["pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
-        elif command_byte == 0x1B: #Load variable [xxyyzz]
-            info = "Load variable [xxyy][zz]"
-            long_info = """
-            #Writes zz to ram address.
-            #[1B][2-byte RAM address][zz]
-            """
-            size = 4
-            command["pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
-            command["value"] = ord(rom[start_address+3])
-        elif command_byte == 0x1C: #Check codes [xx]
-            #XXX no idea what's going on in this one :(
-            info = "Check pre-ID-mapped RAM location [xx]"
-            long_info = """
-            #Checks special game-technical values and writes then into RAM.
-            #[1C][following part][Ram check (when <> 08/09 see „numbers“ in list of following parts)]
-            #following part (and then hex values)
-            #01 = PKMN count in party
-            #     00 - 06
-            #02 = ???
-            #03 = Battle type of wild PKMN
-            #04 = ???
-            #05 = PokéDex caught
-            #     00 - FA
-            #06 = PokéDex seen
-            #     00 - FA
-            #07 = Badge count
-            #     00 - 10
-            #08 = Movement
-            #     00 = walk
-            #     01 = bike
-            #     02 = slipping
-            #     04 = surfer
-            #     08 = surfing pikachu
-            #09 = HIRO direction
-            #     00 (d)
-            #     01 (u)
-            #     02 (l)
-            #     03 (r)
-            #0A = Time in hours
-            #     00 - 18
-            #0B = Day
-            #     00 (Mo) - 06 (Su)
-            #0C = Map bank of current map
-            #0D = Map no of current map
-            #0E = Num. of diff. unowns seen
-            #     00 - 1A
-            #0F = Action byte of map
-            #10 = Amount of free spaces in pkmn box
-            #     00 - 14
-            #11 = Minutes until end bug contest
-            #     00 - 14
-            #12 = X position of HIRO
-            #13 = Y position of HIRO
-            #14 = phone call number
-            """
-            size = 2 #i think?
-            command["following_part"] = ord(rom[start_address+1])
-        elif command_byte == 0x1D: #Input code1 [xx]
-            info = "Write to pre-ID-mapped RAM location [xx]"
-            long_info = """
-            #Writes variable from RAM to special game-technical value offsets.
-            #[1D][following part]
-            #where [following part] is the same as 0x1C
-            """
-            size = 2
-            command["following_part"] = ord(rom[start_address+1])
-        elif command_byte == 0x1E: #Input code2 [xxyy]
-            info = "Write byte value to pre-ID-mapped RAM location [aa][xx]"
-            long_info = """
-            #Writes variable xx to special game-technical value offsets.
-            #[1E][following part][xx]
-            #where [following part] is the same as 0x1C
-            """
-            size = 3
-            command["following_part"] = ord(rom[start_address+1])
-            command["value"] = ord(rom[start_address+2])
-        elif command_byte == 0x1F: #Give item code [xxyy]
-            info = "Give item by id and quantity [xx][yy]"
-            long_info = """
-            #Gives item (item no) amount times.
-            #feedback:
-            #   00 = bag full
-            #   01 = OK
-            #[1F][item no][amount]
-            """
-            size = 3
-            command["item_id"] = ord(rom[start_address+1])
-            command["quantity"] = ord(rom[start_address+2])
-        elif command_byte == 0x20: #Take item code [xxyy]
-            info = "Take item by id and quantity [xx][yy]"
-            long_info = """
-            #Gives item (item no) amount times
-            #feedback:
-            #   00 = not enough items
-            #[20][item no][amount]
-            """
-            size = 3
-            command["item_id"] = ord(rom[start_address+1])
-            command["quantity"] = ord(rom[start_address+2])
-        elif command_byte == 0x21: #Check for item code [xx]
-            info = "Check if player has item [xx]"
-            long_info = """
-            #Checks if item is possessed.
-            #feedback:
-            #   00 = does not have item
-            #   01 = has item
-            #[21][item no]
-            """
-            size = 2
-            command["item_id"] = ord(rom[start_address+1])
-        elif command_byte == 0x22: #Give money code [xxyyzzaa]
-            info = "Give money to HIRO/account [xxyyzzaa]"
-            long_info = """
-            #Gives zzyyxx money to HIRO/account.
-            #zzyyxx = amount of money (000000 - 0F423F)
-            #[22][00-HIRO/01-account][xxyyzz]
-            """
-            size = 5
-            bytes = rom_interval(start_address, size, strings=False)
-            command["account"] = bytes[1]
-            command["amount"] = bytes[2:]
-            #raise NotImplementedError, "don't know if zzyyxx is a decimal or hex value"
-        elif command_byte == 0x23: #Take money code [xxyyzzaa]
-            info = "Take money from HIRO/account [xxyyzzaa]"
-            long_info = """
-            #Takes zzyyxx money from HIRO/account.
-            #zzyyxx = amount of money (000000 - 0F423F)
-            #[23][00-HIRO/01-account][xxyyzz]
-            """
-            size = 5
-            bytes = rom_interval(start_address, size, strings=False)
-            command["account"] = bytes[1]
-            command["amount"] = bytes[2:]
-            #raise NotImplementedError, "don't know if zzyyxx is a decimal or hex value"
-        elif command_byte == 0x24: #Check for money code [xxyyzzaa]
-            info = "Check if HIRO/account has enough money [xxyyzzaa]"
-            long_info = """
-            #Checks if HIRO/account has got zzyyxx money.
-            #feedback:
-            #   00 = enough money
-            #   01 = exact amount
-            #   02 = less money
-            #zzyyxx = amount of money (000000 - 0F423F)
-            #[24][00-HIRO/01-account][xxyyzz]
-            """
-            size = 5
-            bytes = rom_interval(start_address, size, strings=False)
-            command["account"] = bytes[1]
-            command["quantity"] = bytes[2:]
-            #XXX how is quantity formatted?
-            #raise NotImplementedError, "don't know if zzyyxx is a decimal or hex value"
-        elif command_byte == 0x25: #Give coins code [xxyy]
-            info = "Give coins to HIRO [xxyy]"
-            long_info = """
-            #Gives coins to HIRO.
-            #yyxx = amount of coins (0000 - 270F)
-            #[25][xxyy]
-            """
-            size = 3
-            bytes = rom_interval(start_address, size, strings=False)
-            command["quantity"] = bytes[1] + (bytes[2] << 8)
-        elif command_byte == 0x26: #Take coins code [xxyy]
-            info = "Take coins from HIRO [xxyy]"
-            long_info = """
-            #Takes coins away from HIRO.
-            #yyxx = amount of coins (0000 - 270F)
-            #[26][xxyy]
-            """
-            size = 3
-            bytes = rom_interval(start_address, size, strings=False)
-            command["quantity"] = bytes[1] + (bytes[2] << 8)
-        elif command_byte == 0x27: #Check for coins code [xxyy]
-            info = "Check if HIRO has enough coins [xxyy]"
-            long_info = """
-            #Checks if HIRO has enough coins.
-            #feedback:
-            #   00 = has enough coins
-            #   01 = has exact amount
-            #   02 = does not have enough
-            #yyxx = amount of coins necessary (0000 - 270F)
-            #[27][xxyy]
-            """
-            size = 3
-            bytes = rom_interval(start_address, size, strings=False)
-            command["quantity"] = bytes[1] + (bytes[2] << 8)
-        elif command_byte == 0x28: #Give cell phone number [xx]
-            info = "Give cell phone number [xx]"
-            long_info = """
-            #Gives number to HIRO.
-            #feedback:
-            #   00 = number was added successfully
-            #   01 = Number already added, or no memory
-            #xx = number of person
-            #[28][xx]
-            #01 = mother
-            #02 = bike store
-            #03 = bll
-            #04 = elm
-            """
-            size = 2
-            command["number"] = ord(rom[start_address+1])
-        elif command_byte == 0x29: #Take cell phone number [xx]
-            info = "Delete cell phone number [xx]"
-            long_info = """
-            #Deletes a number from the list.
-            #feedback:
-            #   00 = number deleted successfully
-            #   01 = number wasn't in list
-            #xx = number of person
-            #[29][xx]
-            """
-            size = 2
-            command["number"] = ord(rom[start_address+1])
-        elif command_byte == 0x2A: #Check for cell phone number [xx]
-            info = "Check for cell phone number [xx]"
-            long_info = """
-            #Checks if a number is in the list.
-            #feedback:
-            #   00 = number is in list
-            #   01 = number not in list
-            #xx = number to look for
-            #[2A][xx]
-            """
-            size = 2
-            command["number"] = ord(rom[start_address+1])
-        elif command_byte == 0x2B: #Check time of day [xx]
-            info = "Check time of day [xx]"
-            long_info = """
-            #Checks the time of day.
-            #feedback:
-            #   00 = time of day is the same
-            #   01 = time of day is not the same
-            #[2B][time of day (01morn-04night)]
-            """
-            size = 2
-            command["time_of_day"] = ord(rom[start_address+1])
-        elif command_byte == 0x2C: #Check for PKMN [xx]
-            info = "Check for pokemon [xx]"
-            long_info = """
-            #Checks if there is a certain PKMN in team.
-            #feedback:
-            #   00 = in team
-            #   01 = not in team
-            #xx = pkmn id
-            #[2C][xx]
-            """
-            size = 2
-            command["pokemon_id"] = ord(rom[start_address+1])
-        elif command_byte == 0x2D: #Give PKMN [xxyyzzaa(+2b +2b)]
-            info = "Give pokemon [pokemon][level][item][trainer2b][...]"
-            long_info = """
-            #Gives a PKMN if there's space
-            #feedback:
-            #   trainer id
-            #[2D][PKMN][PKMNlvl][PKMNitem][TRAINER]
-            #trainer:
-            #   00 = HIRO
-            #   01 = after the main code there are 4 bytes added
-            #       [2byte pointer to trainer's name (max.0x0A figures + 0x50)][2byte pointer to nickname (max.0x0A figures + 0x50)]
-            """
-            size = 5
-            bytes = rom_interval(start_address, size, strings=False)
-            command["pokemon_id"] = bytes[1]
-            command["pokemon_level"] = bytes[2]
-            command["held_item_id"] = bytes[3]
-            command["trainer"] = bytes[4]
-            if command["trainer"] == 0x01:
-                size += 4
+                script = rec_parse_script_engine_script_at(pointer, original_start_address, debug=debug)
+                command["pointer"] = pointer
+                command["script"] = script
+            elif command_byte == 0x09: #RAM check [<>0]
+                info = "RAM check [<>0]"
+                long_info = """
+                When the conditional is true...
+                .. then go to pointed script, else resume interpreting after the pointer
+                """
+                size = 3
+                pointer = calculate_pointer_from_bytes_at(start_address+1)
+                if debug:
+                    print "in script starting at "+hex(original_start_address)+\
+                      " about to parse script at "+hex(pointer)+\
+                      " called by "+info+" byte="+hex(command_byte)
+                script = rec_parse_script_engine_script_at(pointer, original_start_address, debug=debug)
+                command["pointer"] = pointer
+                command["script"] = script
+            elif command_byte == 0x0A: #RAM check [<byte]
+                info = "RAM check [<byte]"
+                long_info = """
+                When the conditional is true...
+                .. then go to pointed script, else resume interpreting after the pointer
+                """
+                size = 4
+                command["byte"] = ord(rom[start_address+1])
+                pointer = calculate_pointer_from_bytes_at(start_address+2)
+                if debug:
+                    print "in script starting at "+hex(original_start_address)+\
+                      " about to parse script at "+hex(pointer)+\
+                      " called by "+info+" byte="+hex(command_byte)
+                script = rec_parse_script_engine_script_at(pointer, original_start_address, debug=debug)
+                command["pointer"] = pointer
+                command["script"] = script
+            elif command_byte == 0x0B: #RAM check [>byte]
+                info = "RAM check [>byte]"
+                long_info = """
+                When the conditional is true...
+                .. then go to pointed script, else resume interpreting after the pointer
+                """
+                size = 4
+                command["byte"] = ord(rom[start_address+1])
+                pointer = calculate_pointer_from_bytes_at(start_address+2)
+                if debug:
+                    print "in script starting at "+hex(original_start_address)+\
+                      " about to parse script at "+hex(pointer)+\
+                      " called by "+info+" byte="+hex(command_byte)
+                script = rec_parse_script_engine_script_at(pointer, original_start_address, debug=debug)
+                command["pointer"] = pointer
+                command["script"] = script
+            elif command_byte == 0x0C: #0C codes [xxyy]
+                info = "call predefined script then end"
+                long_info = """
+                Calls predefined scripts. After this code the script ends.
+                [0C][xxyy]
+                """
+                size = 3
+                end = True
+                byte1 = ord(rom[offset+1])
+                byte2 = ord(rom[offset+2])
+                number = byte1 + (byte2 << 8)
+                #0000 to 000AD ... XXX how should these be handled?
+                command["predefined_script_number"] = number
+            elif command_byte == 0x0D: #0D codes [xxyy]
+                info = "call some predefined script"
+                long_info = """
+                Calls predefined scripts. Exactly like $0C except the script does not end.
+                [0D][xxyy]
+                """
+                size = 3
+                byte1 = ord(rom[offset+1])
+                byte2 = ord(rom[offset+2])
+                number = byte1 + (byte2 << 8)
+                #0000 to 000AD ... XXX how should these be handled?
+                command["predefined_script_number"] = number
+            elif command_byte == 0x0E: #ASM code1 [3b]
+                info = "ASM code1 [3b]"
+                long_info = """
+                Calls a predefined routine by interpreting the ASM the pointer points to.
+                [0E][3byte pointer]
+                """
+                size = 4
+                command["pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=True)
+                #XXX should we dissassemble the asm at the target location?
+            elif command_byte == 0x0F: #0F codes [xxyy]
+                info = "call some predefined script [0F][yyxx]"
+                long_info = """
+                Calls predefined scripts.
+                [0F][yyxx]
+                NOTE: For (some) dialogues the font needs to be loaded with the Text box&font code.
+                """
+                size = 3
+                byte1 = ord(rom[offset+1])
+                byte2 = ord(rom[offset+2])
+                number = byte1 + (byte2 << 8)
+                command["predefined_script_number"] = number
+            elif command_byte == 0x10: #ASM code2 [2b]
+                info = "ASM code2 [2b to 3b to asm]"
+                long_info = """
+                Call an ASM script via a 2byte pointer pointing to a 3byte pointer.
+                [10][2byte pointer pointing to 3byte pointer pointing to ASM script]
+                """
+                size = 3
+                command["pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
+                #XXX should i include the 3-byte pointer at the target location?
+                #XXX should we dissassemble the asm at the target location?
+            elif command_byte == 0x11: #Trigger event check1 [xxyy]
+                info = "Trigger event check1 [xx][yy]"
+                long_info = """
+                Check the current number of the trigger event on map (map group/map id).
+                [11][map group][map number]
+                """
+                size = 3
+                command["map_group"] = ord(rom[start_address+1])
+                command["map_id"] = ord(rom[start_address+2])
+            elif command_byte == 0x12: #Activate trigger event from afar [xxyyzz]
+                info = "Activate trigger event from afar [xx][yy][zz]"
+                long_info = """
+                Changes trigger event number on map (map bank/map no) to xx.
+                xx = trigger event number that should be activated
+                [12][MapBank][MapNo][xx]
+                """
+                size = 4
+                command["map_group"] = ord(rom[start_address+1])
+                command["map_id"] = ord(rom[start_address+2])
+                command["trigger_number"] = ord(rom[start_address+3])
+            elif command_byte == 0x13: #Trigger event check
+                info = "Trigger event check"
+                long_info = """
+                Checks the number of the trigger events on the current map.
+                [13]
+                """
+                size = 1
+            elif command_byte == 0x14: #De-/activate trigger event [xx]
+                info = "De-/activate trigger event [xx]"
+                long_info = """
+                Changes trigger event number on current map to xx.
+                xx = trigger event number that should be activated
+                [14][xx]
+                deactivate? Just activate a different trigger event number. There's a limit of 1 active trigger.
+                """
+                size = 2
+                command["trigger_number"] = ord(rom[start_address+1])
+            elif command_byte == 0x15: #Load variable into RAM [xx]
+                info = "Load variable into RAM [xx]"
+                long_info = "[15][xx]"
+                size = 2
+                command["variable"] = ord(rom[start_address+1])
+            elif command_byte == 0x16: #Add variables [xx]
+                info = "Add variables [xx]"
+                long_info = """
+                Adds xx and the variable in RAM.
+                #[16][xx]
+                """
+                size = 2
+                command["variable"] = ord(rom[start_address+1])
+            elif command_byte == 0x17: #Random number [xx]
+                info = "Random number [xx]"
+                long_info = """
+                #Reads xx and creates a random number between 00 and xx -1.
+                #According to this xx can be all but 00. Random number = [00; xx)
+                #The nearer the random number is to xx, the rarer it occurs.
+                #Random number gets written to RAM.
+                """
+                size = 2
+                command["rarest"] = ord(rom[start_address+1])
+            elif command_byte == 0x18: #Version check
+                info = "G/S version check"
+                long_info = """
+                #Check if version is gold or silver. Gives feedback.
+                #00 = Gold
+                #01 = Silver
+                #[18]
+                """
+                size = 1
+            elif command_byte == 0x19: #Copy variable code1 [xxyy]
+                info = "Copy from RAM address to script RAM variable [xxyy]"
+                long_info = """
+                #Writes variable from ram address to RAM.
+                #[19][2-byte RAM address]
+                """
+                size = 3
+                #XXX maybe a pointer is a bad idea?
+                command["pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
+            elif command_byte == 0x1A: #Copy variable code2 [xxyy]
+                info = "Write variable from script RAM variable to actual RAM address [xxyy]"
+                long_info = """
+                #Writes variable from RAM to actual RAM address.
+                #[1A][2-byte RAM address]
+                """
+                size = 3
+                command["pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
+            elif command_byte == 0x1B: #Load variable [xxyyzz]
+                info = "Load variable [xxyy][zz]"
+                long_info = """
+                #Writes zz to ram address.
+                #[1B][2-byte RAM address][zz]
+                """
+                size = 4
+                command["pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
+                command["value"] = ord(rom[start_address+3])
+            elif command_byte == 0x1C: #Check codes [xx]
+                #XXX no idea what's going on in this one :(
+                info = "Check pre-ID-mapped RAM location [xx]"
+                long_info = """
+                #Checks special game-technical values and writes then into RAM.
+                #[1C][following part][Ram check (when <> 08/09 see „numbers“ in list of following parts)]
+                #following part (and then hex values)
+                #01 = PKMN count in party
+                #     00 - 06
+                #02 = ???
+                #03 = Battle type of wild PKMN
+                #04 = ???
+                #05 = PokéDex caught
+                #     00 - FA
+                #06 = PokéDex seen
+                #     00 - FA
+                #07 = Badge count
+                #     00 - 10
+                #08 = Movement
+                #     00 = walk
+                #     01 = bike
+                #     02 = slipping
+                #     04 = surfer
+                #     08 = surfing pikachu
+                #09 = HIRO direction
+                #     00 (d)
+                #     01 (u)
+                #     02 (l)
+                #     03 (r)
+                #0A = Time in hours
+                #     00 - 18
+                #0B = Day
+                #     00 (Mo) - 06 (Su)
+                #0C = Map bank of current map
+                #0D = Map no of current map
+                #0E = Num. of diff. unowns seen
+                #     00 - 1A
+                #0F = Action byte of map
+                #10 = Amount of free spaces in pkmn box
+                #     00 - 14
+                #11 = Minutes until end bug contest
+                #     00 - 14
+                #12 = X position of HIRO
+                #13 = Y position of HIRO
+                #14 = phone call number
+                """
+                size = 2 #i think?
+                command["following_part"] = ord(rom[start_address+1])
+            elif command_byte == 0x1D: #Input code1 [xx]
+                info = "Write to pre-ID-mapped RAM location [xx]"
+                long_info = """
+                #Writes variable from RAM to special game-technical value offsets.
+                #[1D][following part]
+                #where [following part] is the same as 0x1C
+                """
+                size = 2
+                command["following_part"] = ord(rom[start_address+1])
+            elif command_byte == 0x1E: #Input code2 [xxyy]
+                info = "Write byte value to pre-ID-mapped RAM location [aa][xx]"
+                long_info = """
+                #Writes variable xx to special game-technical value offsets.
+                #[1E][following part][xx]
+                #where [following part] is the same as 0x1C
+                """
+                size = 3
+                command["following_part"] = ord(rom[start_address+1])
+                command["value"] = ord(rom[start_address+2])
+            elif command_byte == 0x1F: #Give item code [xxyy]
+                info = "Give item by id and quantity [xx][yy]"
+                long_info = """
+                #Gives item (item no) amount times.
+                #feedback:
+                #   00 = bag full
+                #   01 = OK
+                #[1F][item no][amount]
+                """
+                size = 3
+                command["item_id"] = ord(rom[start_address+1])
+                command["quantity"] = ord(rom[start_address+2])
+            elif command_byte == 0x20: #Take item code [xxyy]
+                info = "Take item by id and quantity [xx][yy]"
+                long_info = """
+                #Gives item (item no) amount times
+                #feedback:
+                #   00 = not enough items
+                #[20][item no][amount]
+                """
+                size = 3
+                command["item_id"] = ord(rom[start_address+1])
+                command["quantity"] = ord(rom[start_address+2])
+            elif command_byte == 0x21: #Check for item code [xx]
+                info = "Check if player has item [xx]"
+                long_info = """
+                #Checks if item is possessed.
+                #feedback:
+                #   00 = does not have item
+                #   01 = has item
+                #[21][item no]
+                """
+                size = 2
+                command["item_id"] = ord(rom[start_address+1])
+            elif command_byte == 0x22: #Give money code [xxyyzzaa]
+                info = "Give money to HIRO/account [xxyyzzaa]"
+                long_info = """
+                #Gives zzyyxx money to HIRO/account.
+                #zzyyxx = amount of money (000000 - 0F423F)
+                #[22][00-HIRO/01-account][xxyyzz]
+                """
+                size = 5
                 bytes = rom_interval(start_address, size, strings=False)
-                command["trainer_name_pointer"] = calculate_pointer_from_bytes_at(start_address+5, bank=False)
-                command["pokemon_nickname_pointer"] = calculate_pointer_from_bytes_at(start_address+7, bank=False)
-        elif command_byte == 0x2E: #Give EGG [xxyy]
-            info = "Give egg [xx][yy]"
-            long_info = """
-            #Gives egg if there's space.
-            #feedback:
-            #   00 = OK
-            #   02 = transaction not complete
-            #[2E][PKMN][PKMNlvl]
-            """
-            size = 3
-            command["pokemon_id"] = ord(rom[start_address+1])
-            command["pokemon_level"] = ord(rom[start_address+2])
-        elif command_byte == 0x2F: #Attach item code [2B]
-            info = "Attach item to last pokemon in list [xxyy]"
-            long_info = """
-            #Gives last PKMN in list an item and letter text if applicable. Replaces existing items.
-            #[2F][2byte pointer to item no + 0x20 bytes letter text]
-            """
-            size = 3
-            command["item_pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
-            #XXX are those 20 bytes supposed to happen here? or at the pointer's destination?
-        elif command_byte == 0x30: #Check letter code [2b]
-            info = "Check letter against known letter [xxyy]"
-            long_info = """
-            #Opens a PKMN list. Selected PKMN must have the right letter + the right contents. If OK, then PKMN is taken away
-            #feedback:
-            #   00 = wrong letter
-            #   01 = OK
-            #   02 = Cancelled
-            #   03 = Chosen PKMN has no letter
-            #   04 = Chosen PKMN is the only one in the list.
-            #[30][2byte pointer to letter item no + 0x20 bytes letter text]
-            """
-            size = 3
-            command["item_pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
-        elif command_byte == 0x31: #BitTable1 check [xxyy]
-            info = "Check some bit on bit table 1 [xxyy]"
-            long_info = """
-            #Checks whether a bit of BitTable1 has the value 0 or 1.
-            #feedback:
-            #   00 = value 0 (off)
-            #   01 = value 1 (on)
-            #[31][2-byte bit number]
-            """
-            #XXX what format is the 2-byte number in?
-            size = 3
-            bytes = rom_interval(start_address+1, size-1, strings=False)
-            command["bit_number_bytes"] = bytes
-            #raise NotImplementedError, "what format is the 2-byte number in?"
-        elif command_byte == 0x32: #BitTable1 reset [xxyy]
-            info = "Reset (to 0) a bit on bit table 1 [xxyy]"
-            long_info = """
-            #Sets a bit of BitTable1 to value 0.
-            #[32][Bit no (2byte)]
-            """
-            size = 3
-            bytes = rom_interval(start_address+1, size-1, strings=False)
-            command["bit_number_bytes"] = bytes
-        elif command_byte == 0x33: #BitTable1 set [xxyy]
-            info = "Set (to 1) a bit on bit table 1 [xxyy]"
-            long_info = """
-            #Sets a bit of BitTable1 to value 1.
-            #[33][Bit-No (2byte)]
-            """
-            size = 3
-            bytes = rom_interval(start_address+1, size-1, strings=False)
-            command["bit_number_bytes"] = bytes
-        elif command_byte == 0x34: #BitTable2 check [xxyy]
-            info = "Check some bit on bit table 2 [xxyy]"
-            long_info = """
-            #Checks whether a bit of BitTable2 has the value 0 or 1.
-            #feedback:
-            #   00 = value 0 (off)
-            #   01 = value 1 (on)
-            #[34][Bit no (2byte)]
-            """
-            size = 3
-            bytes = rom_interval(start_address+1, size-1, strings=False)
-            command["bit_number_bytes"] = bytes
-        elif command_byte == 0x35: #BitTable2 reset [xxyy]
-            info = "Reset (to 0) a bit on bit table 2 [xxyy]"
-            long_info = """
-            #Sets a bit of BitTable2 to value 0.
-            #[35][Bit no (2byte)]
-            """
-            size = 3
-            bytes = rom_interval(start_address+1, size-1, strings=False)
-            command["bit_number_bytes"] = bytes
-        elif command_byte == 0x36: #BitTable2 set [xxyy]
-            info = "Set (to 1) a bit on bit table 2 [xxyy]"
-            long_info = """
-            #Sets a bit of BitTable2 to value 1.
-            #[36][Bit no (2byte)]
-            """
-            size = 3
-            bytes = rom_interval(start_address+1, size-1, strings=False)
-            command["bit_number_bytes"] = bytes
-        elif command_byte == 0x37: #Deactivate PKMN battles
-            info = "Turn off wild pokemon battles"
-            long_info = """
-            #This code turns all wild PKMN battles off.
-            #[37]
-            """
-            size = 1
-        elif command_byte == 0x38: #Activate PKMN battles
-            info = "Turn no wild pokemon battles"
-            long_info = "This code turns all wild PKMN battles on."
-            size = 1
-        elif command_byte == 0x39: #X/Y comparison [xxyy]
-            info = "BUGGY x/y comparison [xxyy]"
-            long_info = """
-            #This code is buggy (Bug fix: 0x3021 --> C6) and can't used as
-            #described without fix. This code compares the X and Y coordinates of
-            #HIRO with the ones in a table (max. 20h XY pairs) on the current map.
-            #It sets or resets the 4 bytes D17C to D17F accordingly to this table,
-            #1 bit for every table entry. To be useful, this code can only be used
-            #in a command queue, because with every regular move of HIRO the bits
-            #are reset again. This code is an alternative to the trigger events and
-            #can be used via the command queue code.
-            #See Write command queue, Additional documentation: 3:4661 with c= index 
-            #in table (start=00), hl=D171, b=01, d=00.
-            """
-            size = 3
-            command["table_pointer"] = rom_interval(start_address+1, size-1, strings=False)
-        elif command_byte == 0x3A: #Warp modifier [xxyyzz]
-            info = "Set target for 0xFF warps [warp id][map group][map id]"
-            long_info = """
-            #Changes warp data for all warps of the current map that have a 0xFF for warp-to data.
-            #[3A][Nee warp-to][New map bank][New map no]
-            """
-            size = 4
-            bytes = rom_interval(start_address+1, size-1, strings=False)
-            command["nee_warp_to"] = bytes[0]
-            command["map_group"] = bytes[1]
-            command["map_id"] = bytes[2]
-        elif command_byte == 0x3B: #Blackout modifier [xxyy]
-            info = "Blackout warp modifier [map group][map id]"
-            long_info = """
-            #Changes the map HIRO arrives at, after having a blackout.
-            #There needs to be flying data for that map.
-            #[3B][Map bank][Map no]
-            """
-            size = 3
-            command["map_group"] = ord(rom[start_address+1])
-            command["map_id"] = ord(rom[start_address+2])
-        elif command_byte == 0x3C: #Warp code [xxyyzzaa]
-            info = "Warp to [map group][map id][x][y]"
-            long_info = """
-            #Warps to another map.
-            #If all data is 00s, then the current map is reloaded with
-            #the current X and Y coordinates. Old script is not finished
-            #without a [90].
-            #[3C][Map bank][Map no][X][Y]
-            """
-            size = 5
-            command["map_group"] = ord(rom[start_address+1])
-            command["map_id"] = ord(rom[start_address+2])
-            command["x"] = ord(rom[start_address+3])
-            command["y"] = ord(rom[start_address+4])
-        elif command_byte == 0x3D: #Account code [xxyy]
-            info = "Read money amount [xx][yy]"
-            long_info = """
-            #Reads amount of money in accounts of HIRO and mother and writes
-            #it to MEMORY1, 2 or 3 for later use in text.
-            #[3D][00 = HIRO| <> 00 = Mother][00-02 MEMORY]
-            #see http://hax.iimarck.us/files/scriptingcodes_eng.htm#InText01
-            """
-            size = 3
-            command["account_id"] = ord(rom[start_address+1])
-            command["memory_id"] = ord(rom[start_address+2])
-        elif command_byte == 0x3E: #Coin case code [xx]
-            info = "Read coins amount [xx]"
-            long_info = """
-            #Reads amount of coins in coin case and writes it to MEMORY 1, 2,
-            #or 3 for later use in text.
-            #[3E][00-02 MEMORY]
-            """
-            size = 2
-            command["memory_id"] = ord(rom[start_address+1])
-        elif command_byte == 0x3F: #Display RAM [xx]
-            info = "Copy script RAM value into memX [xx]"
-            long_info = """
-            #Reads RAM value and writes it to MEMORY1, 2 or 3 for later use in text.
-            #[3F][00-02 MEMORY]
-            """
-            size = 2
-            command["memory_id"] = ord(rom[start_address+1])
-        elif command_byte == 0x40: #Display pokémon name [xxyy]
-            info = "Copy pokemon name (by id) to memX [id][xx]"
-            long_info = """
-            #Writes pokémon name to MEMORY1, 2 or 3 for later use in text.
-            #[40][PKMN no][00-02 MEMORY]
-            """
-            size = 3
-            command["map_id"] = ord(rom[start_address+1])
-            command["memory_id"] = ord(rom[start_address+2])
-        elif command_byte == 0x41: #Display item name [xxyy]
-            info = "Copy item name (by id) to memX [id][xx]"
-            long_info = """
-            #Writes item name to MEMORY1, 2 or 3 for later use in text.
-            #[41][Item no][00-02 MEMORY]
-            """
-            size = 3
-            command["item_id"] = ord(rom[start_address+1])
-            command["memory_id"] = ord(rom[start_address+2])
-        elif command_byte == 0x42: #Display location name [xx]
-            info = "Copy map name to memX [xx]"
-            long_info = """
-            #Writes current location's name to MEMORY1, 2 or 3 for later use in text.
-            #[42][00-02 MEMORY]
-            """
-            size = 2
-            command["memory_id"] = ord(rom[start_address+1])
-        elif command_byte == 0x43: #Display trainer name [xxyyzz]
-            info = "Copy trainer name (by id&group) to memZ [xx][yy][zz]"
-            long_info = """
-            #Writes trainer name to MEMORY1, 2 or 3 for later use in text.
-            #[43][Trainer number][Trainer group][00-02 MEMORY]
-            """
-            size = 4
-            command["trainer_id"] = ord(rom[start_address+1])
-            command["trainer_group"] = ord(rom[start_address+2])
-            command["memory_id"] = ord(rom[start_address+3])
-        elif command_byte == 0x44: #Display strings [2b + xx]
-            info = "Copy text (by pointer) to memX [aabb][xx]"
-            long_info = """
-            #Writes string to MEMORY1, 2 or 3 for later use in text.
-            #[44][2byte pointer to string (max. 0x0C figures + 0x50)][00-02 MEMORY]
-            #See 0C codes: 0C2900, 0C2A00, 0C1B00, 0C2200, Usage of variable strings in text.
-            """
-            size = 4
-            command["pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
-            command["memory_id"] = ord(rom[start_address+3])
-            command["text"] = parse_text_engine_script_at(command["pointer"], map_group=map_group, map_id=map_id, debug=debug)
-        elif command_byte == 0x45: #Stow away item code
-            info = "Show HIRO put the ITEMNAME in the ITEMPOCKET text box"
-            long_info = """
-            #Text box: "HIRO put the ITEMNAME in the ITEMPOCKET."
-            #The item number has to have been loaded beforehand
-            #(e.g. by Give item code).
-            """
-            size = 1
-        elif command_byte == 0x46: #Full item pocket code
-            info = "Show ITEMPOCKET is full textbox"
-            long_info = """
-            #Text box: "ITEMPOCKET is full..." The item number has to have
-            #been loaded beforehand (e.g. by Give item code).
-            """
-            size = 1
-        elif command_byte == 0x47: #Text box&font code
-            info = "Loads the font into the ram and opens a text box."
-            size = 1
-        elif command_byte == 0x48: #Refresh code [xx]
-            info = "Screen refresh [xx]"
-            long_info = """
-            #Executes a complete screen refresh.
-            #[48][xx]
-            #xx is a dummy byte
-            """
-            size = 2
-            command["dummy"] = ord(rom[start_address+1])
-        elif command_byte == 0x49: #Load moving sprites
-            info = "Load moving sprites into memory"
-            long_info = "Loads moving sprites for person events into ram."
-            size = 1
-        elif command_byte == 0x4A: #Load byte to C1CE [xx]
-            info = "Load specific byte to $C1CE [xx]"
-            long_info = """
-            #Loads a byte to C1CE. Seems to have no function in the game.
-            #[4A][Byte]
-            """
-            size = 2
-            command["byte"] = ord(rom[start_address+1])
-        elif command_byte == 0x4B: #Display text [3b]
-            info = "Display text by pointer [bb][xxyy]"
-            long_info = """
-            #Opens a text box and writes text. Doesn't load font.
-            #[4B][Text bank][2byte text pointer]
-            """
-            size = 4
-            command["text_group"] = ord(rom[start_address+1])
-            command["pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=True)
-            command["text"] = parse_text_engine_script_at(command["pointer"], map_group=map_group, map_id=map_id, debug=debug)
-        elif command_byte == 0x4C: #Display text [2b]
-            info = "Display text by pointer [xxyy]"
-            long_info = """
-            #Opens a text box and writes text. Doesn't load font.
-            #[4C][2byte text pointer]
-            """
-            size = 3
-            command["pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
-            command["text"] = parse_text_engine_script_at(command["pointer"], map_group=map_group, map_id=map_id, debug=debug)
-        elif command_byte == 0x4D: #Repeat text [xxyy]
-            info = "Repeat text [FF][FF]"
-            long_info = """
-            #Opens a text box and writes the text written latest resp. whose address was put statically to D175-D177.
-            #Doesn't load font.
-            #[4D][FF][FF]
-            #Without FF for both bytes, no operation occurs
-            """
-            size = 3
-            command["bytes"] = rom_interval(start_address+1, 2, strings=False)
-        elif command_byte == 0x4E: #YES/No box
-            info = "YES/No box"
-            long_info = """
-            #Displays a YES/NO box at X0F/Y07
-            #feedback:
-            #   00 = no
-            #   01 = yes
-            """
-            size = 1
-        elif command_byte == 0x4F: #Menu data code [2b]
-            info = "Load menu data by pointer [xxyy]"
-            long_info = """
-            #Loads data for menus
-            #[4F][2byte pointer to menu data]
-            #see http://hax.iimarck.us/files/scriptingcodes_eng.htm#ZusatzDatA4F
-            """
-            size = 3
-            command["menu_pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
-        elif command_byte == 0x50: #Write backup code
-            info = "Write screen backup"
-            long_info = "Writes backup of parts of the screen the box was overlapping."
-            size = 1
-        elif command_byte == 0x51: #Text1 code [2b]
-            info = "Display text (by pointer), turn to HIRO, end [xxyy]"
-            long_info = """
-            #Displays a text and lets person turn to HIRO.
-            #Afterwards there is no other script interpreted.
-            #Corresponds to 6A + 47 + 4C + 53 + 49 + 90
-            #[51][2byte textpointer]
-            """
-            size = 3
-            end = True
-            command["pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
-            command["text"] = parse_text_engine_script_at(command["pointer"], map_group=map_id, map_id=map_id, debug=debug)
-        elif command_byte == 0x53: #Text2 code [2b]
-            info = "Display text (by pointer) and end [xxyy]"
-            long_info = """
-            #Displays a text. Afterwards there is no other script interpreted.
-            #Corresponds to 47 + 4C + 53 + 49 + 90
-            #[52][2byte textpointer]
-            """
-            size = 3
-            end = True
-            command["pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
-            command["text"] = parse_text_engine_script_at(command["pointer"], map_group=map_id, map_id=map_id, debug=debug)
-        elif command_byte == 0x54: #Close text box code
-            info = "Close text box"
-            long_info = "Closes a text box which was opened by 47 resp. 4B/4C/4D."
-            size = 1
-        elif command_byte == 0x55: #Keep text box open code
-            info = "Keep text box open"
-            long_info = "Keeps a text box open which was opened by 47 resp. 4B/4C/4D."
-            size = 1
-        elif command_byte == 0x56: #Pokémon picture code [xx]
-            info = "Display a pokemon picture in a box by pokemon id [xx]"
-            long_info = """
-            #Opens a box and puts a Pokémon picture into it.
-            #[55][xx]
-            #xx:
-            #    <>00 : Pokémon no
-            #     =00 : Pokémon no gets read from RAM
-            """
-            size = 2
-            command["byte"] = ord(rom[start_address+1])
-        elif command_byte == 0x57: #Pokémon picture YES/NO code
-            info = "?? Display a pokemon picture and a yes/no box"
-            long_info = """
-            #Displays a YES/NO box at X08/Y05.
-            #feedback:
-            #   00 = no chosen
-            #   01 = yes chosen
-            """
-            size = 1
-        elif command_byte == 0x58: #Menu interpreter 1
-            info = "Menu interpreter 1 (see menu loader)"
-            long_info = """
-            #Interprets menu data loaded by 4F.
-            #see also http://hax.iimarck.us/files/scriptingcodes_eng.htm#ZusatzDatA57
-            """
-            size = 1
-        elif command_byte == 0x59: #Menu interpreter 2
-            info = "Menu interpreter 2 (see menu loader)"
-            long_info = """
-            #Interprets menu data loaded by 4F.
-            #see also http://hax.iimarck.us/files/scriptingcodes_eng.htm#Marke57
-            #see also http://hax.iimarck.us/files/scriptingcodes_eng.htm#ZusatzDatA58
-            """
-            size = 1
-        elif command_byte == 0x5A: #Load Pikachu data
-            info = "Load pikachu data"
-            long_info = "Loads 0x19 (Pikachu) to PokéRAM and level 5 to LevelRAM."
-            size = 1
-        elif command_byte == 0x5B: #Delete FightRAM/reset person check
-            info = "? Disable fleeing from battle"
-            long_info = """
-            #Deletes the value in BattleRAM.
-            #Turns off the check if the battle was started by entering
-            #a trainer's area of view.
-            """
-            size = 1
-        elif command_byte == 0x5C: #Load trainer data1
-            info = "Load trainer from RAM"
-            long_info = """
-            #Loads trainer data when HIRO is in a trainer's range of sight.
-            #Trainer group is read from CF2E and written to
-            #TrRAM1, the trainer number is read from CF2F and written to
-            #TrRAM2. 81 is written to BattleRAM.
-            """
-            size = 1
-        elif command_byte == 0x5D: #Load Pokémon data [xxyy]
-            info = "Loads pokemon by id and level for BattleRAM [xx][yy]"
-            long_info = """
-            #Loads Pokémon data. Writes 80 to BattleRAM.
-            #[5C][Poke no][Level]
-            """
-            size = 3
-            command["pokemon_id"] = ord(rom[start_address+1])
-            command["pokemon_level"] = ord(rom[start_address+2])
-        elif command_byte == 0x5E: #Load trainer data2 [xxyy]
-            info = "Load trainer by group/id for BattleRAM [xx][yy]"
-            long_info = """
-            #Loads trainer data. Trainer group --> TrRAM1,
-            #trainer number --> TrRAM2. Writes 81 to BattleRAM.
-            #[5D][Trainer group][Trainer no]
-            """
-            size = 3
-            command["trainer_group"] = ord(rom[start_address+1])
-            command["trainer_id"] = ord(rom[start_address+2])
-        elif command_byte == 0x5F: #Start battle
-            info = "Start pre-configured battle"
-            long_info = """
-            #Starts trainer or Pokémon battle. BattleRAM: 80 = Poké battle; 81 = Trainer battle.
-            #feedback:
-            #   00 = win
-            #   01 = lose
-            """
-            size = 1
-        elif command_byte == 0x60: #Return to In game engine after battle
-            info = "Return to in-game engine after battle"
-            long_info = "Returns to ingame engine and evaluates battle. When lost then return to last Pokémon Center etc."
-            size = 1
-        elif command_byte == 0x61: #Learn how to catch PKMN [xx]
-            info = "Pokemon catching tutorial [xx]"
-            long_info = """
-            #Starts a learn-how-to-catch battle with a Pokémon, whose data needs to be loaded beforehand
-            #see http://hax.iimarck.us/files/scriptingcodes_eng.htm#Marke5C
-            #Player has to have at least 1 Pokémon for it to work.
-            #Items that are statically used: 1xPotion, 5xPoké ball.
-            #[60][xx]
-            #xx: Between 01 and 03. If <> 03 then HIRO sprite instead of dude sprite and kills
-            #itself when using the item system.
-            """
-            size = 2
-            command["byte"] = ord(rom[start_address+1])
-        elif command_byte == 0x62: #Trainer text code
-            info = "Set trainer text by id [xx]"
-            long_info = """
-            #Interprets the data of a in the event structure defined trainer.
-            #[61][xx]
-            #Xx decides which text to use.
-            #xx: Between 00 and 03.
-            #see http://hax.iimarck.us/files/scriptingcodes_eng.htm#Eventaufbau
-            """
-            size = 2
-            command["byte"] = ord(rom[start_address+1])
-        elif command_byte == 0x63: #Trainer status code [xx]
-            info = "? Check trainer status [xx]"
-            long_info = """
-            #Checks/changes the status of a in the event structure defined trainer.
-            #see http://hax.iimarck.us/files/scriptingcodes_eng.htm#Eventaufbau
-            #[62][xx]
-            #xx is:
-            #   00 = deactivate
-            #   01 = activate
-            #   02 = check
-            """
-            size = 2
-            command["byte"] = ord(rom[start_address+1])
-        elif command_byte == 0x64: #Pointer Win/Lose [2b + 2b]
-            info = "Set win/lose pointers for battle [xxyy][xxyy]"
-            long_info = """
-            #Writes the win/lose pointer of a battle into the ram.
-            #[63][2byte pointer to text Win][2byte pointer to text Loss*]
-            #* When pointer = 0000 then "Blackout" instead of return to gameplay.
-            """
-            size = 5
-            command["won_pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
-            command["lost_pointer"] = calculate_pointer_from_bytes_at(start_address+3, bank=False)
-            command["text_won"] = parse_text_engine_script_at(command["won_pointer"], map_group=map_id, map_id=map_id, debug=debug)
-            command["text_lost"] = parse_text_engine_script_at(command["lost_pointer"], map_group=map_id, map_id=map_id, debug=debug)
-        elif command_byte == 0x65: #Script talk-after
-            #XXX this is a really poor description of whatever this is
-            info = "? Load the trainer talk-after script"
-            long_info = """
-            #Interprets which script is going to be run, when a in the event-structure-defined
-            #trainer is talked to again.
-            #see http://hax.iimarck.us/files/scriptingcodes_eng.htm#Eventaufbau
-            #[64]
-            """
-            size = 1
-        elif command_byte == 0x66: #Script talk-after-cancel
-            info = "Disable/cancel trainer after-battle text"
-            long_info = """
-            #Cancels the talk-after script of the in the event-structure-defined
-            #trainer when talk-after script is executed just after the battle.
-            #[65]
-            """
-            size = 1
-        elif command_byte == 0x67: #Script talk-after-check
-            #XXX also bad explanation/name...
-            info = "? Check if trainer talk-after script is executed just after battle or not"
-            long_info = """
-            #Checks if the talk-after script of the event structure defined trainer
-            #is executed just after the battle or at a later point in time.
-            #feedback:
-            #   00 = no
-            #   01 = yes
-            #[66]
-            """
-            size = 1
-        elif command_byte == 0x68: #Set talked-to person [xx]
-            info = "Set last talked-to person [xx]"
-            long_info = """
-            #Sets the number of the last person talked to.
-            #[67][person]
-            """
-            size = 2
-            command["person_id"] = ord(rom[start_address+1])
-        elif command_byte == 0x69: #Moving code [xx + 2b]
-            info = "Move person (by id) with moving data (by pointer) [id][xxyy]"
-            long_info = """
-            #Moves the person using moving data.
-            #[68][Person][2byte pointer to moving data]
-            #see also http://hax.iimarck.us/files/scriptingcodes_eng.htm#ZusatzB68bis69
-            """
-            size = 4
-            command["person_id"] = ord(rom[start_address+1])
-            command["moving_data_pointer"] = calculate_pointer_from_bytes_at(start_address+2, bank=False)
-        elif command_byte == 0x6A: #Moving code for talked-to person [2b]
-            info = "Move talked-to person with moving data (by pointer) [xxyy]"
-            long_info = """
-            #Moves talked-to person using moving data.
-            #[69][2byte pointer to moving data]
-            """
-            size = 3
-            command["moving_data_pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
-        elif command_byte == 0x6B: #Talk-to facing code
-            info = "Move talked-to person's facing direction to HIRO"
-            long_info = """
-            #Turns the heads of the talked-to persons to HIRO.
-            #[6A]
-            """
-            size = 1
-        elif command_byte == 0x6C: #Facing of people code [xxyy]
-            info = "Move facing direction of person1 to look at person2 [2][1]"
-            long_info = """
-            #Turns the head of person1 to another person2.
-            #[6B][Person2][Person1]
-            #Person2 = If number is greater than 0xFD, then use number of talked-to person.
-            #Person1 = If number equals 0xFE, then take number of talked-to person.
-            """
-            size = 3
-            command["person2_id"] = ord(rom[start_address+1])
-            command["person1_id"] = ord(rom[start_address+2])
-        elif command_byte == 0x6D: #Variable sprites [xxyy]
-            info = "Store value in variable sprite RAM location x by id Y [xx][yy]"
-            long_info = """
-            #Writes a number to the variable sprite RAM from D555 to D564 (see Compendium on the sprite system).
-            #[6C][xx][Sprite no]
-            #xx: Number between 0x00 and 0x0F
-            """
-            size = 3
-            command["number"] = ord(rom[start_address+1])
-            command["sprite_id"] = ord(rom[start_address+2])
-        elif command_byte == 0x6E: #Hide person [xx]
-            info = "Hide person by id [xx]"
-            long_info = """
-            #Hides a person.
-            #[6D][person id]
-            """
-            size = 2
-            command["person_id"] = ord(rom[start_address+1])
-        elif command_byte == 0x6F: #Show person [xx]
-            info = "Show person by id [xx]"
-            long_info = """
-            #Shows a hidden person again.
-            #[6E][person id]
-            """
-            size = 2
-            command["person_id"] = ord(rom[start_address+1])
-        elif command_byte == 0x70: #Following code1 [xxyy]
-            info = "Following code1 [leader id][follower id]"
-            long_info = """
-            #A person1 follows another person2. The person1 that follows
-            #just repeats the movement of person2, even if the persons are
-            #not directly next to each other.
-            #[6F][Leader Person2][Follower Person1]
-            """
-            size = 3
-            command["leader_person_id"] = ord(rom[start_address+1])
-            command["follower_person_id"] = ord(rom[start_address+2])
-        elif command_byte == 0x71: #Stop following code
-            info = "Stop all follow code"
-            long_info = "Ends all current follow codes."
-            size = 1
-        elif command_byte == 0x72: #Move person [xxyyzz]
-            info = "Move person by id to xy [id][xx][yy]"
-            long_info = """
-            #Sets the X/Y values of a person anew.
-            #The person doesn't get shown immediately. Use hide&show.
-            #[71][Person][X][Y]
-            """
-            size = 4
-            command["person_id"] = ord(rom[start_address+1])
-            command["x"] = ord(rom[start_address+2])
-            command["y"] = ord(rom[start_address+3])
-        elif command_byte == 0x73: #Write person location [xx] (lock person location?)
-            info = "Lock person's location by id [id]"
-            long_info = """
-            #Writes the current X/Y values of a person into the ram.
-            #The person is going to stand at its current location even when
-            #it's out of HIRO's sight and is not going to return to its old
-            #location until the next map load.
-            #[72][person]
-            """
-            size = 2
-            command["person_id"] = ord(rom[start_address+1])
-        elif command_byte == 0x74: #Load emoticons [xx]
-            info = "Load emoticon bubble [xx]"
-            long_info = """
-            #Loads the emoticon bubble depending on the given bubble number.
-            #[73][bubble number]
-            #xx: If xx = FF then take number from RAM.
-            #  00 = Exclamation mark
-            #  01 = Question mark
-            #  02 = Happy
-            #  03 = Sad
-            #  04 = Heart
-            #  05 = Flash
-            #  06 = Snoring
-            #  07 = Fish
-            """
-            size = 2
-            command["bubble_number"] = ord(rom[start_address+1])
-        elif command_byte == 0x75: #Display emoticon [xxyyzz]
-            info = "Display emoticon by bubble id and person id and time [xx][yy][zz]"
-            long_info = """
-            #Displays the bubble above a persons head for the given time period.
-            #Attention: Bubbles get loaded into ram!
-            #[74][Bubble][Person][Time]
-            #for bubble ids see 0x73
-            """
-            size = 4
-            command["bubble_number"] = ord(rom[start_address+1])
-            command["person_id"] = ord(rom[start_address+2])
-            command["time"] = ord(rom[start_address+3])
-        elif command_byte == 0x76: #Change facing [xxyy]
-            info = "Set facing direction of person [person][facing]"
-            long_info = """
-            #Changes the facing direction of a person.
-            #[75][person][facing]
-            """
-            size = 3
-            command["person_id"] = ord(rom[start_address+1])
-            command["facing"] = ord(rom[start_address+2])
-        elif command_byte == 0x77: #Following code2 [xxyy]
-            info = "Following code2 [leader id][follower id]"
-            long_info = """
-            #A person1 follows a person2. The following person1 automatically clings to person2.
-            #Person1 just follows person2, but doesn't make the exact same movements at person2.
-            #[76][Leader Person2][Follower Person1]
-            """
-            size = 3
-            command["leader_person_id"] = ord(rom[start_address+1])
-            command["follower_person_id"] = ord(rom[start_address+2])
-        elif command_byte == 0x78: #Earth quake [xx]
-            info = "Earthquake [xx]"
-            long_info = """
-            #The screen shakes. xx gives time as well as displacement of the screen.
-            #[77][xx]
-            """
-            size = 2
-            command["shake_byte"] = ord(rom[start_address+1])
-        elif command_byte == 0x79: #Exchange map [3b]
-            info = "Draw map data over current map [bank][pointer]"
-            long_info = """
-            #This code draws another whole map as wide and high as the
-            #current map over the current map.
-            #The 3byte pointer points to the new map.
-            #[78][3byte pointer to new map data]
-            """
-            size = 4
-            command["map_data_pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=True)
-        elif command_byte == 0x7A: #Change block code [xxyyzz]
-            info = "Change block to block id on map [xx][yy][id]"
-            long_info = """
-            #Changes a block on the current map by giving the new block
-            #number and its X/Y values measured in half-blocks.
-            #[79][X][Y][Block]
-            """
-            size = 4
-            command["x"] = ord(rom[start_address+1])
-            command["y"] = ord(rom[start_address+2])
-            command["block"] = ord(rom[start_address+3])
-        elif command_byte == 0x7B: #Reload map code
-            info = "Reload/redisplay map"
-            long_info = """
-            #Reloads and re-displays the map completely.
-            #Loads tileset and all map data anew. Screen gets light.
-            #[7A]
-            """
-            size = 1
-        elif command_byte == 0x7C: #Reload map part code
-            info = "Reload/redisplay map portion occupied by HIRO"
-            long_info = """
-            #Reloads and re-displays the part of the map HIRO is on,
-            #without reloading any other map data or the tileset.
-            #[7B]
-            """
-            size = 1
-        elif command_byte == 0x7D: #Write command queue
-            info = "Write command queue [xxyy]"
-            long_info = """
-            #Writes a command queue to the next free slot in ram.
-            #Max 4 command queues à 5 bytes. This code is buggy (bug fix: 25:7C74 --> 12).
-            #[7C][2byte pointer to 5byte command queue]
-            #see http://hax.iimarck.us/files/scriptingcodes_eng.htm#ZusatzDok25_7CC9
-            """
-            size = 3
-            command["command_queue_pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
-        elif command_byte == 0x7E: #Delete command queue
-            info = "Delete command queue"
-            long_info = """
-            #Deletes a command queue and frees a slot in ram.
-            #[7D][First command of the resp. queue]
-            """
-            #XXX wtf?
-            size = 2
-            command["first_command"] = ord(rom[start_address+1])
-        elif command_byte == 0x7F: #Song code1 [xxyy]
-            info = "Play music by number [xxyy]"
-            long_info = """
-            #Immediately plays the music.
-            #[7E][Music no (2byte)]
-            #Music no: See the music archive that should accompany
-            #this document Thanks to Filb. He dumped all the songs
-            #via gameboy player and gave them to me.
-            """
-            size = 3
-            #XXX what is the format of this music data?
-            command["music_number"] = rom_interval(start_address+1, size-1, strings=False)
-        elif command_byte == 0x80: #Song code2
-            info = "Song code2"
-            long_info = """
-            #Plays the music of the trainer group in TrRAM1.
-            #Takes music numbers from list at 3A:5027.
-            #[7F]
-            """
-            size = 1
-        elif command_byte == 0x81: #Music fade-out code [xxyy][zz]
-            info = "Music fade-out then play next [xxyy][time]"
-            long_info = """
-            #The current music is faded out and the new music is played afterwards.
-            #[80][Music no (2byte)][Time to fade out (00-7F)]
-            """
-            size = 4
-            command["music_number"] = rom_interval(start_address+1, 2, strings=False)
-            command["fade_time"] = ord(rom[start_address+3])
-        elif command_byte == 0x82: #Play map music code
-            info = "Play map's music"
-            long_info = """
-            #Starts playing the original map music.
-            #Includes special check for surfer and bug contest song.
-            #[81]
-            """
-            size = 1
-        elif command_byte == 0x83: #Map reload music code
-            info = "Reload map music"
-            long_info = """
-            #After a map reload no music is played.
-            #[82]
-            """
-            size = 1
-        elif command_byte == 0x84: #Cry code [xx00]
-            info = "Play cry by id or RAM [cry][00]"
-            long_info = """
-            #Plays the Pokémon's cry.
-            #[83][Cry no][00]
-            #If the cry no = 00 then the number is taken from RAM.
-            """
-            size = 3
-            command["cry_number"] = ord(rom[start_address+1])
-            command["other_byte"] = ord(rom[start_address+2])
-        elif command_byte == 0x85: #Sound code [xxyy]
-            info = "Play sound by sound number [xxyy]"
-            long_info = """
-            #Plays the sound.
-            #[84][Sound no (2byte)]
-            #Sound no: See the music archive that should accompany this document
-            #Thanks to philb for this matter. He helped me to record a big
-            #part of these sounds.
-            """
-            size = 3
-            command["sound_number"] = rom_interval(start_address+1, 2, strings=False)
-        elif command_byte == 0x86: #Key-down code
-            info = "Wait for key-down"
-            long_info = """
-            #Waits for the Player to press a button.
-            #[85]
-            """
-            size = 1
-        elif command_byte == 0x87: #Warp sound
-            info = "Warp sound"
-            long_info = """
-            #Evaluates which sound is played when HIRO enters a Warp field.
-            #Usage via script ingame is rather not useful.
-            #[86]
-            """
-            size = 1
-        elif command_byte == 0x88: #Special sound
-            info = "Special sound if TM was last checked"
-            long_info = """
-            #When last given/checked Item was a TM then it plays sound 0x9B. If not, then 0x01.
-            #[87]
-            """
-            size = 1
-        elif command_byte == 0x89: #Engine remote control [2b]
-            info = "Engine remote control [bb][xxyy]"
-            long_info = """
-            #This code controls the engine via "data stream".
-            #[88][3byte pointer to control structure]
-            #see http://hax.iimarck.us/files/scriptingcodes_eng.htm#ZusatzDatA88
-            """
-            size = 4
-            command["data_stream_pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=True)
-        elif command_byte == 0x8A: #Load map anew [xx]
-            info = "Load map with specific loading process [xx]"
-            long_info = """
-            #The number decides which map loading process is used.
-            #The number must be 0xF0 + process number to work correctly.
-            #[89][Number]
-            #see map loading process:
-            #   http://hax.iimarck.us/files/scriptingcodes_eng.htm#ZusatzDok5_5550
-            """
-            size = 2
-            command["number"] = ord(rom[start_address+1])
-        elif command_byte == 0x8B: #Waiting code [xx]
-            info = "Wait code"
-            long_info = """
-            #This code lets the game wait for 2 * xx time intervals.
-            #[8A][xx]
-            #xx: Numbers from 0x01 to 0xFF.
-            #If 0x00 is chosen then the time can be manipulated by previously loading a number to RAM2.
-            """
-            size = 2
-            command["time"] = ord(rom[start_address+1])
-        elif command_byte == 0x8C: #Deactivate static facing [xx]
-            info = "Deactive static facing after time [xx]"
-            long_info = """
-            #Deactivates static facings on all persons on the screen after a time xx.
-            #[8B][xx]
-            """
-            size = 2
-            command["time"] = ord(rom[start_address+1])
-        elif command_byte == 0x8D: #Priority jump1 [2b]
-            info = "Priority jump to script by pointer [xxyy]"
-            long_info = """
-            #The pointer acts like code 00, but with this higher
-            #functions like the bike etc. are not paid attention to,
-            #while the script is running.
-            #[8C][2byte pointer to script]
-            """
-            size = 3
-            script_pointer = calculate_pointer_from_bytes_at(start_address+1, bank=False)
-            if debug:
-                print "in script starting at "+hex(original_start_address)+\
-                  " about to parse script at "+hex(script_pointer)+\
-                  " called by "+info+" byte="+hex(command_byte)
-            script = rec_parse_script_engine_script_at(script_pointer, original_start_address, debug=debug)
-            command["script_pointer"] = script_pointer
-            command["script"] = script
-            end = True #according to pksv
-        elif command_byte == 0x8E: #Warp check
-            info = "Reactive all engine checks if player is warping"
-            long_info = """
-            #If HIRO is entering or leaving a warp then this code reactivates all the engine-checks.
-            #[8D]
-            """
-            size = 1
-        elif command_byte == 0x8F: #Priority jump2 [2b]
-            info = "Priority jump to script by pointer (after 1st cycle) [xxyy]"
-            long_info = """
-            #The pointer acts like code 03, but with this code all
-            #higher functions wait for a cycle before the script gets interpreted.
-            #[8E][2byte pointer to script]
-            """
-            size = 3
-            script_pointer = calculate_pointer_from_bytes_at(start_address+1, bank=False)
-            if debug:
-                print "in script starting at "+hex(original_start_address)+\
-                  " about to parse script at "+hex(script_pointer)+\
-                  " called by "+info+" byte="+hex(command_byte)
-            script = rec_parse_script_engine_script_at(script_pointer, original_start_address, debug=debug)
-            command["script_pointer"] = script_pointer
-            command["script"] = script
-            end = True #according to pksv
-        elif command_byte == 0x90: #Return code1
-            info = "Return code 1"
-            long_info = """
-            #Ends the current script and loads the backup offset for "linked"
-            #scripts if applicable. The sophisticated functions are not affected
-            #and run like before the code. This code is mostly used for scripts
-            #called by the 2nd part of the script header, because else malfunctions
-            #occur.
-            #[8F]
-            """
-            size = 1
-            end = True
-        elif command_byte == 0x91: #Return code2
-            info = "Return code 2"
-            long_info = """
-            #Ends the current script and loads the backup offset for "linked"
-            #scripts if applicable.  The sophisticated functions get reset if
-            #no backup offset was loaded. This code is used to end most scripts.
-            #[90]
-            """
-            size = 1
-            end = True
-        elif command_byte == 0x92: #Return code3
-            info = "Return code 3"
-            long_info = """
-            #Reloads the map completely like the code 0x7A
-            #and else acts completely like Return code2
-            #[91]
-            #see reload map code
-            #   http://hax.iimarck.us/files/scriptingcodes_eng.htm#Marke7A
-            #see 0x90
-            """
-            size = 1
-            #XXX does this end the script?? "else acts like 0x90"
-            #       else? what's the "if"?
-            end = True
-        elif command_byte == 0x93: #Reset sophisticated functions
-            info = "Reset sophisticated functions"
-            long_info = """
-            #Resets all sophisticated functions to 0.
-            #[92]
-            """
-            size = 1
-        elif command_byte == 0x94: #Mart menu [xxyyzz]
-            info = "Mart menu [dialog no][mart no 2b]"
-            long_info = """
-            #Displays a whole mart menu, however, doesn't load font to ram.
-            #[93][Dialog no][Mart no (2byte)]
-            #see http://hax.iimarck.us/files/scriptingcodes_eng.htm#AwBsp93
-            #see http://hax.iimarck.us/files/scriptingcodes_eng.htm#ZusatzB93
-            """
-            size = 4
-            command["dialog_number"] = ord(rom[start_address+1])
-            command["mart_number"] = rom_interval(start_address+2, 2, strings=False)
-        elif command_byte == 0x95: #Elevator menu [2b]
-            info = "Display elevator menu by pointer [xxyy]"
-            long_info = """
-            #Displays a whole elevator menu, but it doesn't load font to ram.
-            #Only works with warps with warp-to = 0xFF.
-            #[94][2byte pointer to floor list]
-            """
-            size = 3
-            command["floor_list_pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
-        elif command_byte == 0x96: #Trade menu [xx]
-            info = "Display trade menu by trade id [xx]"
-            long_info = """
-            #Displays a whole trade menu, but it doesn't load font to ram.
-            #[95][trade no]
-            #see http://hax.iimarck.us/files/scriptingcodes_eng.htm#ZusatzDokTausch
-            """
-            size = 2
-            command["trade_number"] = ord(rom[start_address+1])
-        elif command_byte == 0x97: #Give cell phone number with YES/NO [xx]
-            info = "Give cell phone number by id with YES/NO [id]"
-            long_info = """
-            #Gives a telephone number but asks for decision beforehand.
-            #feedback:
-            #   00 = ok chosen
-            #   01 = Cell phone number already registered/Memory full
-            #   02 = no chosen
-            #[96][Cell phone number]
-            """
-            size = 2
-            #maybe this next param should be called "phone_number"
-            command["number"] = ord(rom[start_address+1])
-        elif command_byte == 0x98: #Call code [2b]
-            info = "Call code pointing to name of caller [xxyy]"
-            long_info = """
-            #Displays the upper cell phone box and displays a freely selectable name.
-            #[97][2byte pointer to name of caller]
-            """
-            size = 3
-            command["caller_name_pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
-        elif command_byte == 0x99: #Hang-up code
-            info = "Hang-up phone"
-            long_info = """
-            #Simulates the hanging-up.
-            #[98]
-            """
-            size = 1
-        elif command_byte == 0x9A: #Decoration code [xx]
-            info = "Set monologue decoration [xx]"
-            long_info = """
-            #Displays monologues according to the selected ornament.
-            #[99][xx]
-            #xx values:
-            #  00 = Map/Poster
-            #  01 = Ornament left
-            #  02 = Ornament right
-            #  03 = Huge doll
-            #  04 = Console
-            """
-            size = 2
-            command["ornament"] = ord(rom[start_address+1])
-        elif command_byte == 0x9B: #Berry tree code [xx]
-            info = "Berry tree by tree id [xx]"
-            long_info = """
-            #Creates a typical berry tree monologue.
-            #There is a maximum of 32 berry trees in the game.
-            #After this code the script ends.
-            #[9A][Fruit tree number]
-            #Fruit tree number + 11:4091 is the offset where the item no of the berry is defined.
-            """
-            size = 2
-            end = True
-            command["tree_id"] = ord(rom[start_address+1])
-        elif command_byte == 0x9C: #Cell phone call code [xx00]
-            #XXX confirm this?
-            info = "Cell phone call [2-byte call id]" #was originally: [call id][00]
-            long_info = """
-            #Initiates with the next step on a outer world map (permission byte) a phone call.
-            #[9B][Call no] and maybe [00] ???
-            #call no:
-            #  01 = PokéRus
-            #  02 = Pokémon stolen
-            #  03 = Egg examined/ Assistant in Viola City
-            #  04 = Team Rocket on the radio
-            #  05 = PROF. ELM has got something for HIRO
-            #  06 = Bike shop gives bike away
-            #  07 = Mother is unhappy that HIRO didn't talk to her before leaving
-            #  08 = PROF. ELM has got something for HIRO a second time
-            """
-            size = 3
-            command["call_id"] = ord(rom[start_address+1])
-            command["id"] = rom_interval(start_address+2, 2, strings=False)
-        elif command_byte == 0x9D: #Check cell phone call code
-            info = "Check if/which a phone call is active"
-            long_info = """
-            #Checks if a phone call is "in the line".
-            #feedback:
-            #   00 = no
-            # <>00 = call number
-            #[9C]
-            """
-            size = 1
-        elif command_byte == 0x9E: #Commented give item code [xxyy]
-            info = "Give item by id and quantity with 'put in pocket' text [id][qty]"
-            long_info = """
-            #The same as 0x1F but this code comments where
-            #HIRO puts what item in a short monologue.
-            #[9D][Item][Amount]
-            """
-            size = 3
-            command["item_id"] = ord(rom[start_address+1])
-            command["quantity"] = ord(rom[start_address+2])
-        elif command_byte == 0x9F: #Commented ive item code?
-            info = "Give item by id and quantity with 'put in pocket' text [id][qty]"
-            long_info = """
-            #The same as 0x1F but this code comments where
-            #HIRO puts what item in a short monologue.
-            #[9D][Item][Amount]
-            """
-            size = 3
-            command["item_id"] = ord(rom[start_address+1])
-            command["quantity"] = ord(rom[start_address+2])
-        elif command_byte == 0xA0: #Load special wild PKMN data [xxyy]
-            info = "Load wild pokemon data for a remote map [map group][map id]"
-            long_info = """
-            #Activates the checks in the special tables for the wild pokémon data.
-            #[9E][map group][map id]
-            #see also http://hax.iimarck.us/files/scriptingcodes_eng.htm#ZusatzDok3E_66ED
-            """
-            size = 3
-            command["map_group"] = ord(rom[start_address+1])
-            command["map_id"] = ord(rom[start_address+2])
-        elif command_byte == 0xA1: #Hall of Fame code
-            info = "Hall of Fame"
-            long_info = """
-            #Saves and enters HIRO's complete Team in the Hall of Fame.
-            #Shows the credits and restarts the game with HIRO located in New Bark Town.
-            #[9F]
-            """
-            size = 1
-        elif command_byte == 0xA2: #Credits code
-            info = "Credits"
-            long_info = """
-            #Shows the credits and HIRO is located on the Silver mountain plateau.
-            #[A0]
-            """
-            size = 1
-        elif command_byte == 0xA3: #Facing warp
-            info = "Warp-to and set facing direction [Facing (00-03)][Map bank][Map no][X][Y]"
-            long_info = """
-            #Acts like code 0x3C but defines the desired facing of HIRO.
-            #[A1][Facing (00-03)][Map bank][Map no][X][Y]
-            """
-            size = 6
-            command["facing"] = ord(rom[start_address+1])
-            command["map_group"] = ord(rom[start_address+2])
-            command["map_id"] = ord(rom[start_address+3])
-            command["x"] = ord(rom[start_address+4])
-            command["y"] = ord(rom[start_address+5])
-        elif command_byte == 0xA4: #MEMORY code [2b + Bank + xx]
-            info = "Set memX to a string by a pointer [aabb][bank][xx]"
-            long_info = """
-            #MEMORY1, 2 or 3 can directly be filled with a string from
-            #a different rom bank.
-            #[A2][2byte pointer][Bank][00-02 MEMORY]
-            """
-            size = 5
-            command["string_pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank="reversed")
-            command["string_pointer_bank"] = ord(rom[start_address+3])
-            command["memory_id"] = ord(rom[start_address+4])
-        elif command_byte == 0xA5: #Display any location name [xx]
-            info = "Copy the name of a location (by id) to TEMPMEMORY1"
-            long_info = """
-            #By the location number the name of that location is written to TEMPMEMORY1.
-            #[A3][Location no]
-            """
-            size = 2
-            command["location_number"] = ord(rom[start_address+1])
-        else:
-            size = 1
-            #end = True
-            #raise NotImplementedError, "command byte is " + hex(command_byte) + " at " + hex(offset) + " on map " + str(map_group) + "." + str(map_id)
-            print "dunno what this command is: " + hex(command_byte)
-        long_info = clean_up_long_info(long_info)
-        
-        if command_byte in pksv_crystal.keys():
-            pksv_name = pksv_crystal[command_byte]
-        else:
-            pksv_name = None
-            if command_byte in pksv_no_names.keys():
-                pksv_no_names[command_byte].append(address)
+                command["account"] = bytes[1]
+                command["amount"] = bytes[2:]
+                #raise NotImplementedError, "don't know if zzyyxx is a decimal or hex value"
+            elif command_byte == 0x23: #Take money code [xxyyzzaa]
+                info = "Take money from HIRO/account [xxyyzzaa]"
+                long_info = """
+                #Takes zzyyxx money from HIRO/account.
+                #zzyyxx = amount of money (000000 - 0F423F)
+                #[23][00-HIRO/01-account][xxyyzz]
+                """
+                size = 5
+                bytes = rom_interval(start_address, size, strings=False)
+                command["account"] = bytes[1]
+                command["amount"] = bytes[2:]
+                #raise NotImplementedError, "don't know if zzyyxx is a decimal or hex value"
+            elif command_byte == 0x24: #Check for money code [xxyyzzaa]
+                info = "Check if HIRO/account has enough money [xxyyzzaa]"
+                long_info = """
+                #Checks if HIRO/account has got zzyyxx money.
+                #feedback:
+                #   00 = enough money
+                #   01 = exact amount
+                #   02 = less money
+                #zzyyxx = amount of money (000000 - 0F423F)
+                #[24][00-HIRO/01-account][xxyyzz]
+                """
+                size = 5
+                bytes = rom_interval(start_address, size, strings=False)
+                command["account"] = bytes[1]
+                command["quantity"] = bytes[2:]
+                #XXX how is quantity formatted?
+                #raise NotImplementedError, "don't know if zzyyxx is a decimal or hex value"
+            elif command_byte == 0x25: #Give coins code [xxyy]
+                info = "Give coins to HIRO [xxyy]"
+                long_info = """
+                #Gives coins to HIRO.
+                #yyxx = amount of coins (0000 - 270F)
+                #[25][xxyy]
+                """
+                size = 3
+                bytes = rom_interval(start_address, size, strings=False)
+                command["quantity"] = bytes[1] + (bytes[2] << 8)
+            elif command_byte == 0x26: #Take coins code [xxyy]
+                info = "Take coins from HIRO [xxyy]"
+                long_info = """
+                #Takes coins away from HIRO.
+                #yyxx = amount of coins (0000 - 270F)
+                #[26][xxyy]
+                """
+                size = 3
+                bytes = rom_interval(start_address, size, strings=False)
+                command["quantity"] = bytes[1] + (bytes[2] << 8)
+            elif command_byte == 0x27: #Check for coins code [xxyy]
+                info = "Check if HIRO has enough coins [xxyy]"
+                long_info = """
+                #Checks if HIRO has enough coins.
+                #feedback:
+                #   00 = has enough coins
+                #   01 = has exact amount
+                #   02 = does not have enough
+                #yyxx = amount of coins necessary (0000 - 270F)
+                #[27][xxyy]
+                """
+                size = 3
+                bytes = rom_interval(start_address, size, strings=False)
+                command["quantity"] = bytes[1] + (bytes[2] << 8)
+            elif command_byte == 0x28: #Give cell phone number [xx]
+                info = "Give cell phone number [xx]"
+                long_info = """
+                #Gives number to HIRO.
+                #feedback:
+                #   00 = number was added successfully
+                #   01 = Number already added, or no memory
+                #xx = number of person
+                #[28][xx]
+                #01 = mother
+                #02 = bike store
+                #03 = bll
+                #04 = elm
+                """
+                size = 2
+                command["number"] = ord(rom[start_address+1])
+            elif command_byte == 0x29: #Take cell phone number [xx]
+                info = "Delete cell phone number [xx]"
+                long_info = """
+                #Deletes a number from the list.
+                #feedback:
+                #   00 = number deleted successfully
+                #   01 = number wasn't in list
+                #xx = number of person
+                #[29][xx]
+                """
+                size = 2
+                command["number"] = ord(rom[start_address+1])
+            elif command_byte == 0x2A: #Check for cell phone number [xx]
+                info = "Check for cell phone number [xx]"
+                long_info = """
+                #Checks if a number is in the list.
+                #feedback:
+                #   00 = number is in list
+                #   01 = number not in list
+                #xx = number to look for
+                #[2A][xx]
+                """
+                size = 2
+                command["number"] = ord(rom[start_address+1])
+            elif command_byte == 0x2B: #Check time of day [xx]
+                info = "Check time of day [xx]"
+                long_info = """
+                #Checks the time of day.
+                #feedback:
+                #   00 = time of day is the same
+                #   01 = time of day is not the same
+                #[2B][time of day (01morn-04night)]
+                """
+                size = 2
+                command["time_of_day"] = ord(rom[start_address+1])
+            elif command_byte == 0x2C: #Check for PKMN [xx]
+                info = "Check for pokemon [xx]"
+                long_info = """
+                #Checks if there is a certain PKMN in team.
+                #feedback:
+                #   00 = in team
+                #   01 = not in team
+                #xx = pkmn id
+                #[2C][xx]
+                """
+                size = 2
+                command["pokemon_id"] = ord(rom[start_address+1])
+            elif command_byte == 0x2D: #Give PKMN [xxyyzzaa(+2b +2b)]
+                info = "Give pokemon [pokemon][level][item][trainer2b][...]"
+                long_info = """
+                #Gives a PKMN if there's space
+                #feedback:
+                #   trainer id
+                #[2D][PKMN][PKMNlvl][PKMNitem][TRAINER]
+                #trainer:
+                #   00 = HIRO
+                #   01 = after the main code there are 4 bytes added
+                #       [2byte pointer to trainer's name (max.0x0A figures + 0x50)][2byte pointer to nickname (max.0x0A figures + 0x50)]
+                """
+                size = 5
+                bytes = rom_interval(start_address, size, strings=False)
+                command["pokemon_id"] = bytes[1]
+                command["pokemon_level"] = bytes[2]
+                command["held_item_id"] = bytes[3]
+                command["trainer"] = bytes[4]
+                if command["trainer"] == 0x01:
+                    size += 4
+                    bytes = rom_interval(start_address, size, strings=False)
+                    command["trainer_name_pointer"] = calculate_pointer_from_bytes_at(start_address+5, bank=False)
+                    command["pokemon_nickname_pointer"] = calculate_pointer_from_bytes_at(start_address+7, bank=False)
+            elif command_byte == 0x2E: #Give EGG [xxyy]
+                info = "Give egg [xx][yy]"
+                long_info = """
+                #Gives egg if there's space.
+                #feedback:
+                #   00 = OK
+                #   02 = transaction not complete
+                #[2E][PKMN][PKMNlvl]
+                """
+                size = 3
+                command["pokemon_id"] = ord(rom[start_address+1])
+                command["pokemon_level"] = ord(rom[start_address+2])
+            elif command_byte == 0x2F: #Attach item code [2B]
+                info = "Attach item to last pokemon in list [xxyy]"
+                long_info = """
+                #Gives last PKMN in list an item and letter text if applicable. Replaces existing items.
+                #[2F][2byte pointer to item no + 0x20 bytes letter text]
+                """
+                size = 3
+                command["item_pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
+                #XXX are those 20 bytes supposed to happen here? or at the pointer's destination?
+            elif command_byte == 0x30: #Check letter code [2b]
+                info = "Check letter against known letter [xxyy]"
+                long_info = """
+                #Opens a PKMN list. Selected PKMN must have the right letter + the right contents. If OK, then PKMN is taken away
+                #feedback:
+                #   00 = wrong letter
+                #   01 = OK
+                #   02 = Cancelled
+                #   03 = Chosen PKMN has no letter
+                #   04 = Chosen PKMN is the only one in the list.
+                #[30][2byte pointer to letter item no + 0x20 bytes letter text]
+                """
+                size = 3
+                command["item_pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
+            elif command_byte == 0x31: #BitTable1 check [xxyy]
+                info = "Check some bit on bit table 1 [xxyy]"
+                long_info = """
+                #Checks whether a bit of BitTable1 has the value 0 or 1.
+                #feedback:
+                #   00 = value 0 (off)
+                #   01 = value 1 (on)
+                #[31][2-byte bit number]
+                """
+                #XXX what format is the 2-byte number in?
+                size = 3
+                bytes = rom_interval(start_address+1, size-1, strings=False)
+                command["bit_number_bytes"] = bytes
+                #raise NotImplementedError, "what format is the 2-byte number in?"
+            elif command_byte == 0x32: #BitTable1 reset [xxyy]
+                info = "Reset (to 0) a bit on bit table 1 [xxyy]"
+                long_info = """
+                #Sets a bit of BitTable1 to value 0.
+                #[32][Bit no (2byte)]
+                """
+                size = 3
+                bytes = rom_interval(start_address+1, size-1, strings=False)
+                command["bit_number_bytes"] = bytes
+            elif command_byte == 0x33: #BitTable1 set [xxyy]
+                info = "Set (to 1) a bit on bit table 1 [xxyy]"
+                long_info = """
+                #Sets a bit of BitTable1 to value 1.
+                #[33][Bit-No (2byte)]
+                """
+                size = 3
+                bytes = rom_interval(start_address+1, size-1, strings=False)
+                command["bit_number_bytes"] = bytes
+            elif command_byte == 0x34: #BitTable2 check [xxyy]
+                info = "Check some bit on bit table 2 [xxyy]"
+                long_info = """
+                #Checks whether a bit of BitTable2 has the value 0 or 1.
+                #feedback:
+                #   00 = value 0 (off)
+                #   01 = value 1 (on)
+                #[34][Bit no (2byte)]
+                """
+                size = 3
+                bytes = rom_interval(start_address+1, size-1, strings=False)
+                command["bit_number_bytes"] = bytes
+            elif command_byte == 0x35: #BitTable2 reset [xxyy]
+                info = "Reset (to 0) a bit on bit table 2 [xxyy]"
+                long_info = """
+                #Sets a bit of BitTable2 to value 0.
+                #[35][Bit no (2byte)]
+                """
+                size = 3
+                bytes = rom_interval(start_address+1, size-1, strings=False)
+                command["bit_number_bytes"] = bytes
+            elif command_byte == 0x36: #BitTable2 set [xxyy]
+                info = "Set (to 1) a bit on bit table 2 [xxyy]"
+                long_info = """
+                #Sets a bit of BitTable2 to value 1.
+                #[36][Bit no (2byte)]
+                """
+                size = 3
+                bytes = rom_interval(start_address+1, size-1, strings=False)
+                command["bit_number_bytes"] = bytes
+            elif command_byte == 0x37: #Deactivate PKMN battles
+                info = "Turn off wild pokemon battles"
+                long_info = """
+                #This code turns all wild PKMN battles off.
+                #[37]
+                """
+                size = 1
+            elif command_byte == 0x38: #Activate PKMN battles
+                info = "Turn no wild pokemon battles"
+                long_info = "This code turns all wild PKMN battles on."
+                size = 1
+            elif command_byte == 0x39: #X/Y comparison [xxyy]
+                info = "BUGGY x/y comparison [xxyy]"
+                long_info = """
+                #This code is buggy (Bug fix: 0x3021 --> C6) and can't used as
+                #described without fix. This code compares the X and Y coordinates of
+                #HIRO with the ones in a table (max. 20h XY pairs) on the current map.
+                #It sets or resets the 4 bytes D17C to D17F accordingly to this table,
+                #1 bit for every table entry. To be useful, this code can only be used
+                #in a command queue, because with every regular move of HIRO the bits
+                #are reset again. This code is an alternative to the trigger events and
+                #can be used via the command queue code.
+                #See Write command queue, Additional documentation: 3:4661 with c= index 
+                #in table (start=00), hl=D171, b=01, d=00.
+                """
+                size = 3
+                command["table_pointer"] = rom_interval(start_address+1, size-1, strings=False)
+            elif command_byte == 0x3A: #Warp modifier [xxyyzz]
+                info = "Set target for 0xFF warps [warp id][map group][map id]"
+                long_info = """
+                #Changes warp data for all warps of the current map that have a 0xFF for warp-to data.
+                #[3A][Nee warp-to][New map bank][New map no]
+                """
+                size = 4
+                bytes = rom_interval(start_address+1, size-1, strings=False)
+                command["nee_warp_to"] = bytes[0]
+                command["map_group"] = bytes[1]
+                command["map_id"] = bytes[2]
+            elif command_byte == 0x3B: #Blackout modifier [xxyy]
+                info = "Blackout warp modifier [map group][map id]"
+                long_info = """
+                #Changes the map HIRO arrives at, after having a blackout.
+                #There needs to be flying data for that map.
+                #[3B][Map bank][Map no]
+                """
+                size = 3
+                command["map_group"] = ord(rom[start_address+1])
+                command["map_id"] = ord(rom[start_address+2])
+            elif command_byte == 0x3C: #Warp code [xxyyzzaa]
+                info = "Warp to [map group][map id][x][y]"
+                long_info = """
+                #Warps to another map.
+                #If all data is 00s, then the current map is reloaded with
+                #the current X and Y coordinates. Old script is not finished
+                #without a [90].
+                #[3C][Map bank][Map no][X][Y]
+                """
+                size = 5
+                command["map_group"] = ord(rom[start_address+1])
+                command["map_id"] = ord(rom[start_address+2])
+                command["x"] = ord(rom[start_address+3])
+                command["y"] = ord(rom[start_address+4])
+            elif command_byte == 0x3D: #Account code [xxyy]
+                info = "Read money amount [xx][yy]"
+                long_info = """
+                #Reads amount of money in accounts of HIRO and mother and writes
+                #it to MEMORY1, 2 or 3 for later use in text.
+                #[3D][00 = HIRO| <> 00 = Mother][00-02 MEMORY]
+                #see http://hax.iimarck.us/files/scriptingcodes_eng.htm#InText01
+                """
+                size = 3
+                command["account_id"] = ord(rom[start_address+1])
+                command["memory_id"] = ord(rom[start_address+2])
+            elif command_byte == 0x3E: #Coin case code [xx]
+                info = "Read coins amount [xx]"
+                long_info = """
+                #Reads amount of coins in coin case and writes it to MEMORY 1, 2,
+                #or 3 for later use in text.
+                #[3E][00-02 MEMORY]
+                """
+                size = 2
+                command["memory_id"] = ord(rom[start_address+1])
+            elif command_byte == 0x3F: #Display RAM [xx]
+                info = "Copy script RAM value into memX [xx]"
+                long_info = """
+                #Reads RAM value and writes it to MEMORY1, 2 or 3 for later use in text.
+                #[3F][00-02 MEMORY]
+                """
+                size = 2
+                command["memory_id"] = ord(rom[start_address+1])
+            elif command_byte == 0x40: #Display pokémon name [xxyy]
+                info = "Copy pokemon name (by id) to memX [id][xx]"
+                long_info = """
+                #Writes pokémon name to MEMORY1, 2 or 3 for later use in text.
+                #[40][PKMN no][00-02 MEMORY]
+                """
+                size = 3
+                command["map_id"] = ord(rom[start_address+1])
+                command["memory_id"] = ord(rom[start_address+2])
+            elif command_byte == 0x41: #Display item name [xxyy]
+                info = "Copy item name (by id) to memX [id][xx]"
+                long_info = """
+                #Writes item name to MEMORY1, 2 or 3 for later use in text.
+                #[41][Item no][00-02 MEMORY]
+                """
+                size = 3
+                command["item_id"] = ord(rom[start_address+1])
+                command["memory_id"] = ord(rom[start_address+2])
+            elif command_byte == 0x42: #Display location name [xx]
+                info = "Copy map name to memX [xx]"
+                long_info = """
+                #Writes current location's name to MEMORY1, 2 or 3 for later use in text.
+                #[42][00-02 MEMORY]
+                """
+                size = 2
+                command["memory_id"] = ord(rom[start_address+1])
+            elif command_byte == 0x43: #Display trainer name [xxyyzz]
+                info = "Copy trainer name (by id&group) to memZ [xx][yy][zz]"
+                long_info = """
+                #Writes trainer name to MEMORY1, 2 or 3 for later use in text.
+                #[43][Trainer number][Trainer group][00-02 MEMORY]
+                """
+                size = 4
+                command["trainer_id"] = ord(rom[start_address+1])
+                command["trainer_group"] = ord(rom[start_address+2])
+                command["memory_id"] = ord(rom[start_address+3])
+            elif command_byte == 0x44: #Display strings [2b + xx]
+                info = "Copy text (by pointer) to memX [aabb][xx]"
+                long_info = """
+                #Writes string to MEMORY1, 2 or 3 for later use in text.
+                #[44][2byte pointer to string (max. 0x0C figures + 0x50)][00-02 MEMORY]
+                #See 0C codes: 0C2900, 0C2A00, 0C1B00, 0C2200, Usage of variable strings in text.
+                """
+                size = 4
+                command["pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
+                command["memory_id"] = ord(rom[start_address+3])
+                command["text"] = parse_text_engine_script_at(command["pointer"], map_group=map_group, map_id=map_id, debug=debug)
+            elif command_byte == 0x45: #Stow away item code
+                info = "Show HIRO put the ITEMNAME in the ITEMPOCKET text box"
+                long_info = """
+                #Text box: "HIRO put the ITEMNAME in the ITEMPOCKET."
+                #The item number has to have been loaded beforehand
+                #(e.g. by Give item code).
+                """
+                size = 1
+            elif command_byte == 0x46: #Full item pocket code
+                info = "Show ITEMPOCKET is full textbox"
+                long_info = """
+                #Text box: "ITEMPOCKET is full..." The item number has to have
+                #been loaded beforehand (e.g. by Give item code).
+                """
+                size = 1
+            elif command_byte == 0x47: #Text box&font code
+                info = "Loads the font into the ram and opens a text box."
+                size = 1
+            elif command_byte == 0x48: #Refresh code [xx]
+                info = "Screen refresh [xx]"
+                long_info = """
+                #Executes a complete screen refresh.
+                #[48][xx]
+                #xx is a dummy byte
+                """
+                size = 2
+                command["dummy"] = ord(rom[start_address+1])
+            elif command_byte == 0x49: #Load moving sprites
+                info = "Load moving sprites into memory"
+                long_info = "Loads moving sprites for person events into ram."
+                size = 1
+            elif command_byte == 0x4A: #Load byte to C1CE [xx]
+                info = "Load specific byte to $C1CE [xx]"
+                long_info = """
+                #Loads a byte to C1CE. Seems to have no function in the game.
+                #[4A][Byte]
+                """
+                size = 2
+                command["byte"] = ord(rom[start_address+1])
+            elif command_byte == 0x4B: #Display text [3b]
+                info = "Display text by pointer [bb][xxyy]"
+                long_info = """
+                #Opens a text box and writes text. Doesn't load font.
+                #[4B][Text bank][2byte text pointer]
+                """
+                size = 4
+                command["text_group"] = ord(rom[start_address+1])
+                command["pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=True)
+                command["text"] = parse_text_engine_script_at(command["pointer"], map_group=map_group, map_id=map_id, debug=debug)
+            elif command_byte == 0x4C: #Display text [2b]
+                info = "Display text by pointer [xxyy]"
+                long_info = """
+                #Opens a text box and writes text. Doesn't load font.
+                #[4C][2byte text pointer]
+                """
+                size = 3
+                command["pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
+                command["text"] = parse_text_engine_script_at(command["pointer"], map_group=map_group, map_id=map_id, debug=debug)
+            elif command_byte == 0x4D: #Repeat text [xxyy]
+                info = "Repeat text [FF][FF]"
+                long_info = """
+                #Opens a text box and writes the text written latest resp. whose address was put statically to D175-D177.
+                #Doesn't load font.
+                #[4D][FF][FF]
+                #Without FF for both bytes, no operation occurs
+                """
+                size = 3
+                command["bytes"] = rom_interval(start_address+1, 2, strings=False)
+            elif command_byte == 0x4E: #YES/No box
+                info = "YES/No box"
+                long_info = """
+                #Displays a YES/NO box at X0F/Y07
+                #feedback:
+                #   00 = no
+                #   01 = yes
+                """
+                size = 1
+            elif command_byte == 0x4F: #Menu data code [2b]
+                info = "Load menu data by pointer [xxyy]"
+                long_info = """
+                #Loads data for menus
+                #[4F][2byte pointer to menu data]
+                #see http://hax.iimarck.us/files/scriptingcodes_eng.htm#ZusatzDatA4F
+                """
+                size = 3
+                command["menu_pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
+            elif command_byte == 0x50: #Write backup code
+                info = "Write screen backup"
+                long_info = "Writes backup of parts of the screen the box was overlapping."
+                size = 1
+            elif command_byte == 0x51: #Text1 code [2b]
+                info = "Display text (by pointer), turn to HIRO, end [xxyy]"
+                long_info = """
+                #Displays a text and lets person turn to HIRO.
+                #Afterwards there is no other script interpreted.
+                #Corresponds to 6A + 47 + 4C + 53 + 49 + 90
+                #[51][2byte textpointer]
+                """
+                size = 3
+                end = True
+                command["pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
+                command["text"] = parse_text_engine_script_at(command["pointer"], map_group=map_id, map_id=map_id, debug=debug)
+            elif command_byte == 0x53: #Text2 code [2b]
+                info = "Display text (by pointer) and end [xxyy]"
+                long_info = """
+                #Displays a text. Afterwards there is no other script interpreted.
+                #Corresponds to 47 + 4C + 53 + 49 + 90
+                #[52][2byte textpointer]
+                """
+                size = 3
+                end = True
+                command["pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
+                command["text"] = parse_text_engine_script_at(command["pointer"], map_group=map_id, map_id=map_id, debug=debug)
+            elif command_byte == 0x54: #Close text box code
+                info = "Close text box"
+                long_info = "Closes a text box which was opened by 47 resp. 4B/4C/4D."
+                size = 1
+            elif command_byte == 0x55: #Keep text box open code
+                info = "Keep text box open"
+                long_info = "Keeps a text box open which was opened by 47 resp. 4B/4C/4D."
+                size = 1
+            elif command_byte == 0x56: #Pokémon picture code [xx]
+                info = "Display a pokemon picture in a box by pokemon id [xx]"
+                long_info = """
+                #Opens a box and puts a Pokémon picture into it.
+                #[55][xx]
+                #xx:
+                #    <>00 : Pokémon no
+                #     =00 : Pokémon no gets read from RAM
+                """
+                size = 2
+                command["byte"] = ord(rom[start_address+1])
+            elif command_byte == 0x57: #Pokémon picture YES/NO code
+                info = "?? Display a pokemon picture and a yes/no box"
+                long_info = """
+                #Displays a YES/NO box at X08/Y05.
+                #feedback:
+                #   00 = no chosen
+                #   01 = yes chosen
+                """
+                size = 1
+            elif command_byte == 0x58: #Menu interpreter 1
+                info = "Menu interpreter 1 (see menu loader)"
+                long_info = """
+                #Interprets menu data loaded by 4F.
+                #see also http://hax.iimarck.us/files/scriptingcodes_eng.htm#ZusatzDatA57
+                """
+                size = 1
+            elif command_byte == 0x59: #Menu interpreter 2
+                info = "Menu interpreter 2 (see menu loader)"
+                long_info = """
+                #Interprets menu data loaded by 4F.
+                #see also http://hax.iimarck.us/files/scriptingcodes_eng.htm#Marke57
+                #see also http://hax.iimarck.us/files/scriptingcodes_eng.htm#ZusatzDatA58
+                """
+                size = 1
+            elif command_byte == 0x5A: #Load Pikachu data
+                info = "Load pikachu data"
+                long_info = "Loads 0x19 (Pikachu) to PokéRAM and level 5 to LevelRAM."
+                size = 1
+            elif command_byte == 0x5B: #Delete FightRAM/reset person check
+                info = "? Disable fleeing from battle"
+                long_info = """
+                #Deletes the value in BattleRAM.
+                #Turns off the check if the battle was started by entering
+                #a trainer's area of view.
+                """
+                size = 1
+            elif command_byte == 0x5C: #Load trainer data1
+                info = "Load trainer from RAM"
+                long_info = """
+                #Loads trainer data when HIRO is in a trainer's range of sight.
+                #Trainer group is read from CF2E and written to
+                #TrRAM1, the trainer number is read from CF2F and written to
+                #TrRAM2. 81 is written to BattleRAM.
+                """
+                size = 1
+            elif command_byte == 0x5D: #Load Pokémon data [xxyy]
+                info = "Loads pokemon by id and level for BattleRAM [xx][yy]"
+                long_info = """
+                #Loads Pokémon data. Writes 80 to BattleRAM.
+                #[5C][Poke no][Level]
+                """
+                size = 3
+                command["pokemon_id"] = ord(rom[start_address+1])
+                command["pokemon_level"] = ord(rom[start_address+2])
+            elif command_byte == 0x5E: #Load trainer data2 [xxyy]
+                info = "Load trainer by group/id for BattleRAM [xx][yy]"
+                long_info = """
+                #Loads trainer data. Trainer group --> TrRAM1,
+                #trainer number --> TrRAM2. Writes 81 to BattleRAM.
+                #[5D][Trainer group][Trainer no]
+                """
+                size = 3
+                command["trainer_group"] = ord(rom[start_address+1])
+                command["trainer_id"] = ord(rom[start_address+2])
+            elif command_byte == 0x5F: #Start battle
+                info = "Start pre-configured battle"
+                long_info = """
+                #Starts trainer or Pokémon battle. BattleRAM: 80 = Poké battle; 81 = Trainer battle.
+                #feedback:
+                #   00 = win
+                #   01 = lose
+                """
+                size = 1
+            elif command_byte == 0x60: #Return to In game engine after battle
+                info = "Return to in-game engine after battle"
+                long_info = "Returns to ingame engine and evaluates battle. When lost then return to last Pokémon Center etc."
+                size = 1
+            elif command_byte == 0x61: #Learn how to catch PKMN [xx]
+                info = "Pokemon catching tutorial [xx]"
+                long_info = """
+                #Starts a learn-how-to-catch battle with a Pokémon, whose data needs to be loaded beforehand
+                #see http://hax.iimarck.us/files/scriptingcodes_eng.htm#Marke5C
+                #Player has to have at least 1 Pokémon for it to work.
+                #Items that are statically used: 1xPotion, 5xPoké ball.
+                #[60][xx]
+                #xx: Between 01 and 03. If <> 03 then HIRO sprite instead of dude sprite and kills
+                #itself when using the item system.
+                """
+                size = 2
+                command["byte"] = ord(rom[start_address+1])
+            elif command_byte == 0x62: #Trainer text code
+                info = "Set trainer text by id [xx]"
+                long_info = """
+                #Interprets the data of a in the event structure defined trainer.
+                #[61][xx]
+                #Xx decides which text to use.
+                #xx: Between 00 and 03.
+                #see http://hax.iimarck.us/files/scriptingcodes_eng.htm#Eventaufbau
+                """
+                size = 2
+                command["byte"] = ord(rom[start_address+1])
+            elif command_byte == 0x63: #Trainer status code [xx]
+                info = "? Check trainer status [xx]"
+                long_info = """
+                #Checks/changes the status of a in the event structure defined trainer.
+                #see http://hax.iimarck.us/files/scriptingcodes_eng.htm#Eventaufbau
+                #[62][xx]
+                #xx is:
+                #   00 = deactivate
+                #   01 = activate
+                #   02 = check
+                """
+                size = 2
+                command["byte"] = ord(rom[start_address+1])
+            elif command_byte == 0x64: #Pointer Win/Lose [2b + 2b]
+                info = "Set win/lose pointers for battle [xxyy][xxyy]"
+                long_info = """
+                #Writes the win/lose pointer of a battle into the ram.
+                #[63][2byte pointer to text Win][2byte pointer to text Loss*]
+                #* When pointer = 0000 then "Blackout" instead of return to gameplay.
+                """
+                size = 5
+                command["won_pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
+                command["lost_pointer"] = calculate_pointer_from_bytes_at(start_address+3, bank=False)
+                command["text_won"] = parse_text_engine_script_at(command["won_pointer"], map_group=map_id, map_id=map_id, debug=debug)
+                command["text_lost"] = parse_text_engine_script_at(command["lost_pointer"], map_group=map_id, map_id=map_id, debug=debug)
+            elif command_byte == 0x65: #Script talk-after
+                #XXX this is a really poor description of whatever this is
+                info = "? Load the trainer talk-after script"
+                long_info = """
+                #Interprets which script is going to be run, when a in the event-structure-defined
+                #trainer is talked to again.
+                #see http://hax.iimarck.us/files/scriptingcodes_eng.htm#Eventaufbau
+                #[64]
+                """
+                size = 1
+            elif command_byte == 0x66: #Script talk-after-cancel
+                info = "Disable/cancel trainer after-battle text"
+                long_info = """
+                #Cancels the talk-after script of the in the event-structure-defined
+                #trainer when talk-after script is executed just after the battle.
+                #[65]
+                """
+                size = 1
+            elif command_byte == 0x67: #Script talk-after-check
+                #XXX also bad explanation/name...
+                info = "? Check if trainer talk-after script is executed just after battle or not"
+                long_info = """
+                #Checks if the talk-after script of the event structure defined trainer
+                #is executed just after the battle or at a later point in time.
+                #feedback:
+                #   00 = no
+                #   01 = yes
+                #[66]
+                """
+                size = 1
+            elif command_byte == 0x68: #Set talked-to person [xx]
+                info = "Set last talked-to person [xx]"
+                long_info = """
+                #Sets the number of the last person talked to.
+                #[67][person]
+                """
+                size = 2
+                command["person_id"] = ord(rom[start_address+1])
+            elif command_byte == 0x69: #Moving code [xx + 2b]
+                info = "Move person (by id) with moving data (by pointer) [id][xxyy]"
+                long_info = """
+                #Moves the person using moving data.
+                #[68][Person][2byte pointer to moving data]
+                #see also http://hax.iimarck.us/files/scriptingcodes_eng.htm#ZusatzB68bis69
+                """
+                size = 4
+                command["person_id"] = ord(rom[start_address+1])
+                command["moving_data_pointer"] = calculate_pointer_from_bytes_at(start_address+2, bank=False)
+            elif command_byte == 0x6A: #Moving code for talked-to person [2b]
+                info = "Move talked-to person with moving data (by pointer) [xxyy]"
+                long_info = """
+                #Moves talked-to person using moving data.
+                #[69][2byte pointer to moving data]
+                """
+                size = 3
+                command["moving_data_pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
+            elif command_byte == 0x6B: #Talk-to facing code
+                info = "Move talked-to person's facing direction to HIRO"
+                long_info = """
+                #Turns the heads of the talked-to persons to HIRO.
+                #[6A]
+                """
+                size = 1
+            elif command_byte == 0x6C: #Facing of people code [xxyy]
+                info = "Move facing direction of person1 to look at person2 [2][1]"
+                long_info = """
+                #Turns the head of person1 to another person2.
+                #[6B][Person2][Person1]
+                #Person2 = If number is greater than 0xFD, then use number of talked-to person.
+                #Person1 = If number equals 0xFE, then take number of talked-to person.
+                """
+                size = 3
+                command["person2_id"] = ord(rom[start_address+1])
+                command["person1_id"] = ord(rom[start_address+2])
+            elif command_byte == 0x6D: #Variable sprites [xxyy]
+                info = "Store value in variable sprite RAM location x by id Y [xx][yy]"
+                long_info = """
+                #Writes a number to the variable sprite RAM from D555 to D564 (see Compendium on the sprite system).
+                #[6C][xx][Sprite no]
+                #xx: Number between 0x00 and 0x0F
+                """
+                size = 3
+                command["number"] = ord(rom[start_address+1])
+                command["sprite_id"] = ord(rom[start_address+2])
+            elif command_byte == 0x6E: #Hide person [xx]
+                info = "Hide person by id [xx]"
+                long_info = """
+                #Hides a person.
+                #[6D][person id]
+                """
+                size = 2
+                command["person_id"] = ord(rom[start_address+1])
+            elif command_byte == 0x6F: #Show person [xx]
+                info = "Show person by id [xx]"
+                long_info = """
+                #Shows a hidden person again.
+                #[6E][person id]
+                """
+                size = 2
+                command["person_id"] = ord(rom[start_address+1])
+            elif command_byte == 0x70: #Following code1 [xxyy]
+                info = "Following code1 [leader id][follower id]"
+                long_info = """
+                #A person1 follows another person2. The person1 that follows
+                #just repeats the movement of person2, even if the persons are
+                #not directly next to each other.
+                #[6F][Leader Person2][Follower Person1]
+                """
+                size = 3
+                command["leader_person_id"] = ord(rom[start_address+1])
+                command["follower_person_id"] = ord(rom[start_address+2])
+            elif command_byte == 0x71: #Stop following code
+                info = "Stop all follow code"
+                long_info = "Ends all current follow codes."
+                size = 1
+            elif command_byte == 0x72: #Move person [xxyyzz]
+                info = "Move person by id to xy [id][xx][yy]"
+                long_info = """
+                #Sets the X/Y values of a person anew.
+                #The person doesn't get shown immediately. Use hide&show.
+                #[71][Person][X][Y]
+                """
+                size = 4
+                command["person_id"] = ord(rom[start_address+1])
+                command["x"] = ord(rom[start_address+2])
+                command["y"] = ord(rom[start_address+3])
+            elif command_byte == 0x73: #Write person location [xx] (lock person location?)
+                info = "Lock person's location by id [id]"
+                long_info = """
+                #Writes the current X/Y values of a person into the ram.
+                #The person is going to stand at its current location even when
+                #it's out of HIRO's sight and is not going to return to its old
+                #location until the next map load.
+                #[72][person]
+                """
+                size = 2
+                command["person_id"] = ord(rom[start_address+1])
+            elif command_byte == 0x74: #Load emoticons [xx]
+                info = "Load emoticon bubble [xx]"
+                long_info = """
+                #Loads the emoticon bubble depending on the given bubble number.
+                #[73][bubble number]
+                #xx: If xx = FF then take number from RAM.
+                #  00 = Exclamation mark
+                #  01 = Question mark
+                #  02 = Happy
+                #  03 = Sad
+                #  04 = Heart
+                #  05 = Flash
+                #  06 = Snoring
+                #  07 = Fish
+                """
+                size = 2
+                command["bubble_number"] = ord(rom[start_address+1])
+            elif command_byte == 0x75: #Display emoticon [xxyyzz]
+                info = "Display emoticon by bubble id and person id and time [xx][yy][zz]"
+                long_info = """
+                #Displays the bubble above a persons head for the given time period.
+                #Attention: Bubbles get loaded into ram!
+                #[74][Bubble][Person][Time]
+                #for bubble ids see 0x73
+                """
+                size = 4
+                command["bubble_number"] = ord(rom[start_address+1])
+                command["person_id"] = ord(rom[start_address+2])
+                command["time"] = ord(rom[start_address+3])
+            elif command_byte == 0x76: #Change facing [xxyy]
+                info = "Set facing direction of person [person][facing]"
+                long_info = """
+                #Changes the facing direction of a person.
+                #[75][person][facing]
+                """
+                size = 3
+                command["person_id"] = ord(rom[start_address+1])
+                command["facing"] = ord(rom[start_address+2])
+            elif command_byte == 0x77: #Following code2 [xxyy]
+                info = "Following code2 [leader id][follower id]"
+                long_info = """
+                #A person1 follows a person2. The following person1 automatically clings to person2.
+                #Person1 just follows person2, but doesn't make the exact same movements at person2.
+                #[76][Leader Person2][Follower Person1]
+                """
+                size = 3
+                command["leader_person_id"] = ord(rom[start_address+1])
+                command["follower_person_id"] = ord(rom[start_address+2])
+            elif command_byte == 0x78: #Earth quake [xx]
+                info = "Earthquake [xx]"
+                long_info = """
+                #The screen shakes. xx gives time as well as displacement of the screen.
+                #[77][xx]
+                """
+                size = 2
+                command["shake_byte"] = ord(rom[start_address+1])
+            elif command_byte == 0x79: #Exchange map [3b]
+                info = "Draw map data over current map [bank][pointer]"
+                long_info = """
+                #This code draws another whole map as wide and high as the
+                #current map over the current map.
+                #The 3byte pointer points to the new map.
+                #[78][3byte pointer to new map data]
+                """
+                size = 4
+                command["map_data_pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=True)
+            elif command_byte == 0x7A: #Change block code [xxyyzz]
+                info = "Change block to block id on map [xx][yy][id]"
+                long_info = """
+                #Changes a block on the current map by giving the new block
+                #number and its X/Y values measured in half-blocks.
+                #[79][X][Y][Block]
+                """
+                size = 4
+                command["x"] = ord(rom[start_address+1])
+                command["y"] = ord(rom[start_address+2])
+                command["block"] = ord(rom[start_address+3])
+            elif command_byte == 0x7B: #Reload map code
+                info = "Reload/redisplay map"
+                long_info = """
+                #Reloads and re-displays the map completely.
+                #Loads tileset and all map data anew. Screen gets light.
+                #[7A]
+                """
+                size = 1
+            elif command_byte == 0x7C: #Reload map part code
+                info = "Reload/redisplay map portion occupied by HIRO"
+                long_info = """
+                #Reloads and re-displays the part of the map HIRO is on,
+                #without reloading any other map data or the tileset.
+                #[7B]
+                """
+                size = 1
+            elif command_byte == 0x7D: #Write command queue
+                info = "Write command queue [xxyy]"
+                long_info = """
+                #Writes a command queue to the next free slot in ram.
+                #Max 4 command queues à 5 bytes. This code is buggy (bug fix: 25:7C74 --> 12).
+                #[7C][2byte pointer to 5byte command queue]
+                #see http://hax.iimarck.us/files/scriptingcodes_eng.htm#ZusatzDok25_7CC9
+                """
+                size = 3
+                command["command_queue_pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
+            elif command_byte == 0x7E: #Delete command queue
+                info = "Delete command queue"
+                long_info = """
+                #Deletes a command queue and frees a slot in ram.
+                #[7D][First command of the resp. queue]
+                """
+                #XXX wtf?
+                size = 2
+                command["first_command"] = ord(rom[start_address+1])
+            elif command_byte == 0x7F: #Song code1 [xxyy]
+                info = "Play music by number [xxyy]"
+                long_info = """
+                #Immediately plays the music.
+                #[7E][Music no (2byte)]
+                #Music no: See the music archive that should accompany
+                #this document Thanks to Filb. He dumped all the songs
+                #via gameboy player and gave them to me.
+                """
+                size = 3
+                #XXX what is the format of this music data?
+                command["music_number"] = rom_interval(start_address+1, size-1, strings=False)
+            elif command_byte == 0x80: #Song code2
+                info = "Song code2"
+                long_info = """
+                #Plays the music of the trainer group in TrRAM1.
+                #Takes music numbers from list at 3A:5027.
+                #[7F]
+                """
+                size = 1
+            elif command_byte == 0x81: #Music fade-out code [xxyy][zz]
+                info = "Music fade-out then play next [xxyy][time]"
+                long_info = """
+                #The current music is faded out and the new music is played afterwards.
+                #[80][Music no (2byte)][Time to fade out (00-7F)]
+                """
+                size = 4
+                command["music_number"] = rom_interval(start_address+1, 2, strings=False)
+                command["fade_time"] = ord(rom[start_address+3])
+            elif command_byte == 0x82: #Play map music code
+                info = "Play map's music"
+                long_info = """
+                #Starts playing the original map music.
+                #Includes special check for surfer and bug contest song.
+                #[81]
+                """
+                size = 1
+            elif command_byte == 0x83: #Map reload music code
+                info = "Reload map music"
+                long_info = """
+                #After a map reload no music is played.
+                #[82]
+                """
+                size = 1
+            elif command_byte == 0x84: #Cry code [xx00]
+                info = "Play cry by id or RAM [cry][00]"
+                long_info = """
+                #Plays the Pokémon's cry.
+                #[83][Cry no][00]
+                #If the cry no = 00 then the number is taken from RAM.
+                """
+                size = 3
+                command["cry_number"] = ord(rom[start_address+1])
+                command["other_byte"] = ord(rom[start_address+2])
+            elif command_byte == 0x85: #Sound code [xxyy]
+                info = "Play sound by sound number [xxyy]"
+                long_info = """
+                #Plays the sound.
+                #[84][Sound no (2byte)]
+                #Sound no: See the music archive that should accompany this document
+                #Thanks to philb for this matter. He helped me to record a big
+                #part of these sounds.
+                """
+                size = 3
+                command["sound_number"] = rom_interval(start_address+1, 2, strings=False)
+            elif command_byte == 0x86: #Key-down code
+                info = "Wait for key-down"
+                long_info = """
+                #Waits for the Player to press a button.
+                #[85]
+                """
+                size = 1
+            elif command_byte == 0x87: #Warp sound
+                info = "Warp sound"
+                long_info = """
+                #Evaluates which sound is played when HIRO enters a Warp field.
+                #Usage via script ingame is rather not useful.
+                #[86]
+                """
+                size = 1
+            elif command_byte == 0x88: #Special sound
+                info = "Special sound if TM was last checked"
+                long_info = """
+                #When last given/checked Item was a TM then it plays sound 0x9B. If not, then 0x01.
+                #[87]
+                """
+                size = 1
+            elif command_byte == 0x89: #Engine remote control [2b]
+                info = "Engine remote control [bb][xxyy]"
+                long_info = """
+                #This code controls the engine via "data stream".
+                #[88][3byte pointer to control structure]
+                #see http://hax.iimarck.us/files/scriptingcodes_eng.htm#ZusatzDatA88
+                """
+                size = 4
+                command["data_stream_pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=True)
+            elif command_byte == 0x8A: #Load map anew [xx]
+                info = "Load map with specific loading process [xx]"
+                long_info = """
+                #The number decides which map loading process is used.
+                #The number must be 0xF0 + process number to work correctly.
+                #[89][Number]
+                #see map loading process:
+                #   http://hax.iimarck.us/files/scriptingcodes_eng.htm#ZusatzDok5_5550
+                """
+                size = 2
+                command["number"] = ord(rom[start_address+1])
+            elif command_byte == 0x8B: #Waiting code [xx]
+                info = "Wait code"
+                long_info = """
+                #This code lets the game wait for 2 * xx time intervals.
+                #[8A][xx]
+                #xx: Numbers from 0x01 to 0xFF.
+                #If 0x00 is chosen then the time can be manipulated by previously loading a number to RAM2.
+                """
+                size = 2
+                command["time"] = ord(rom[start_address+1])
+            elif command_byte == 0x8C: #Deactivate static facing [xx]
+                info = "Deactive static facing after time [xx]"
+                long_info = """
+                #Deactivates static facings on all persons on the screen after a time xx.
+                #[8B][xx]
+                """
+                size = 2
+                command["time"] = ord(rom[start_address+1])
+            elif command_byte == 0x8D: #Priority jump1 [2b]
+                info = "Priority jump to script by pointer [xxyy]"
+                long_info = """
+                #The pointer acts like code 00, but with this higher
+                #functions like the bike etc. are not paid attention to,
+                #while the script is running.
+                #[8C][2byte pointer to script]
+                """
+                size = 3
+                script_pointer = calculate_pointer_from_bytes_at(start_address+1, bank=False)
+                if debug:
+                    print "in script starting at "+hex(original_start_address)+\
+                      " about to parse script at "+hex(script_pointer)+\
+                      " called by "+info+" byte="+hex(command_byte)
+                script = rec_parse_script_engine_script_at(script_pointer, original_start_address, debug=debug)
+                command["script_pointer"] = script_pointer
+                command["script"] = script
+                end = True #according to pksv
+            elif command_byte == 0x8E: #Warp check
+                info = "Reactive all engine checks if player is warping"
+                long_info = """
+                #If HIRO is entering or leaving a warp then this code reactivates all the engine-checks.
+                #[8D]
+                """
+                size = 1
+            elif command_byte == 0x8F: #Priority jump2 [2b]
+                info = "Priority jump to script by pointer (after 1st cycle) [xxyy]"
+                long_info = """
+                #The pointer acts like code 03, but with this code all
+                #higher functions wait for a cycle before the script gets interpreted.
+                #[8E][2byte pointer to script]
+                """
+                size = 3
+                script_pointer = calculate_pointer_from_bytes_at(start_address+1, bank=False)
+                if debug:
+                    print "in script starting at "+hex(original_start_address)+\
+                      " about to parse script at "+hex(script_pointer)+\
+                      " called by "+info+" byte="+hex(command_byte)
+                script = rec_parse_script_engine_script_at(script_pointer, original_start_address, debug=debug)
+                command["script_pointer"] = script_pointer
+                command["script"] = script
+                end = True #according to pksv
+            elif command_byte == 0x90: #Return code1
+                info = "Return code 1"
+                long_info = """
+                #Ends the current script and loads the backup offset for "linked"
+                #scripts if applicable. The sophisticated functions are not affected
+                #and run like before the code. This code is mostly used for scripts
+                #called by the 2nd part of the script header, because else malfunctions
+                #occur.
+                #[8F]
+                """
+                size = 1
+                end = True
+            elif command_byte == 0x91: #Return code2
+                info = "Return code 2"
+                long_info = """
+                #Ends the current script and loads the backup offset for "linked"
+                #scripts if applicable.  The sophisticated functions get reset if
+                #no backup offset was loaded. This code is used to end most scripts.
+                #[90]
+                """
+                size = 1
+                end = True
+            elif command_byte == 0x92: #Return code3
+                info = "Return code 3"
+                long_info = """
+                #Reloads the map completely like the code 0x7A
+                #and else acts completely like Return code2
+                #[91]
+                #see reload map code
+                #   http://hax.iimarck.us/files/scriptingcodes_eng.htm#Marke7A
+                #see 0x90
+                """
+                size = 1
+                #XXX does this end the script?? "else acts like 0x90"
+                #       else? what's the "if"?
+                end = True
+            elif command_byte == 0x93: #Reset sophisticated functions
+                info = "Reset sophisticated functions"
+                long_info = """
+                #Resets all sophisticated functions to 0.
+                #[92]
+                """
+                size = 1
+            elif command_byte == 0x94: #Mart menu [xxyyzz]
+                info = "Mart menu [dialog no][mart no 2b]"
+                long_info = """
+                #Displays a whole mart menu, however, doesn't load font to ram.
+                #[93][Dialog no][Mart no (2byte)]
+                #see http://hax.iimarck.us/files/scriptingcodes_eng.htm#AwBsp93
+                #see http://hax.iimarck.us/files/scriptingcodes_eng.htm#ZusatzB93
+                """
+                size = 4
+                command["dialog_number"] = ord(rom[start_address+1])
+                command["mart_number"] = rom_interval(start_address+2, 2, strings=False)
+            elif command_byte == 0x95: #Elevator menu [2b]
+                info = "Display elevator menu by pointer [xxyy]"
+                long_info = """
+                #Displays a whole elevator menu, but it doesn't load font to ram.
+                #Only works with warps with warp-to = 0xFF.
+                #[94][2byte pointer to floor list]
+                """
+                size = 3
+                command["floor_list_pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
+            elif command_byte == 0x96: #Trade menu [xx]
+                info = "Display trade menu by trade id [xx]"
+                long_info = """
+                #Displays a whole trade menu, but it doesn't load font to ram.
+                #[95][trade no]
+                #see http://hax.iimarck.us/files/scriptingcodes_eng.htm#ZusatzDokTausch
+                """
+                size = 2
+                command["trade_number"] = ord(rom[start_address+1])
+            elif command_byte == 0x97: #Give cell phone number with YES/NO [xx]
+                info = "Give cell phone number by id with YES/NO [id]"
+                long_info = """
+                #Gives a telephone number but asks for decision beforehand.
+                #feedback:
+                #   00 = ok chosen
+                #   01 = Cell phone number already registered/Memory full
+                #   02 = no chosen
+                #[96][Cell phone number]
+                """
+                size = 2
+                #maybe this next param should be called "phone_number"
+                command["number"] = ord(rom[start_address+1])
+            elif command_byte == 0x98: #Call code [2b]
+                info = "Call code pointing to name of caller [xxyy]"
+                long_info = """
+                #Displays the upper cell phone box and displays a freely selectable name.
+                #[97][2byte pointer to name of caller]
+                """
+                size = 3
+                command["caller_name_pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank=False)
+            elif command_byte == 0x99: #Hang-up code
+                info = "Hang-up phone"
+                long_info = """
+                #Simulates the hanging-up.
+                #[98]
+                """
+                size = 1
+            elif command_byte == 0x9A: #Decoration code [xx]
+                info = "Set monologue decoration [xx]"
+                long_info = """
+                #Displays monologues according to the selected ornament.
+                #[99][xx]
+                #xx values:
+                #  00 = Map/Poster
+                #  01 = Ornament left
+                #  02 = Ornament right
+                #  03 = Huge doll
+                #  04 = Console
+                """
+                size = 2
+                command["ornament"] = ord(rom[start_address+1])
+            elif command_byte == 0x9B: #Berry tree code [xx]
+                info = "Berry tree by tree id [xx]"
+                long_info = """
+                #Creates a typical berry tree monologue.
+                #There is a maximum of 32 berry trees in the game.
+                #After this code the script ends.
+                #[9A][Fruit tree number]
+                #Fruit tree number + 11:4091 is the offset where the item no of the berry is defined.
+                """
+                size = 2
+                end = True
+                command["tree_id"] = ord(rom[start_address+1])
+            elif command_byte == 0x9C: #Cell phone call code [xx00]
+                #XXX confirm this?
+                info = "Cell phone call [2-byte call id]" #was originally: [call id][00]
+                long_info = """
+                #Initiates with the next step on a outer world map (permission byte) a phone call.
+                #[9B][Call no] and maybe [00] ???
+                #call no:
+                #  01 = PokéRus
+                #  02 = Pokémon stolen
+                #  03 = Egg examined/ Assistant in Viola City
+                #  04 = Team Rocket on the radio
+                #  05 = PROF. ELM has got something for HIRO
+                #  06 = Bike shop gives bike away
+                #  07 = Mother is unhappy that HIRO didn't talk to her before leaving
+                #  08 = PROF. ELM has got something for HIRO a second time
+                """
+                size = 3
+                command["call_id"] = ord(rom[start_address+1])
+                command["id"] = rom_interval(start_address+2, 2, strings=False)
+            elif command_byte == 0x9D: #Check cell phone call code
+                info = "Check if/which a phone call is active"
+                long_info = """
+                #Checks if a phone call is "in the line".
+                #feedback:
+                #   00 = no
+                # <>00 = call number
+                #[9C]
+                """
+                size = 1
+            elif command_byte == 0x9E: #Commented give item code [xxyy]
+                info = "Give item by id and quantity with 'put in pocket' text [id][qty]"
+                long_info = """
+                #The same as 0x1F but this code comments where
+                #HIRO puts what item in a short monologue.
+                #[9D][Item][Amount]
+                """
+                size = 3
+                command["item_id"] = ord(rom[start_address+1])
+                command["quantity"] = ord(rom[start_address+2])
+            elif command_byte == 0x9F: #Commented ive item code?
+                info = "Give item by id and quantity with 'put in pocket' text [id][qty]"
+                long_info = """
+                #The same as 0x1F but this code comments where
+                #HIRO puts what item in a short monologue.
+                #[9D][Item][Amount]
+                """
+                size = 3
+                command["item_id"] = ord(rom[start_address+1])
+                command["quantity"] = ord(rom[start_address+2])
+            elif command_byte == 0xA0: #Load special wild PKMN data [xxyy]
+                info = "Load wild pokemon data for a remote map [map group][map id]"
+                long_info = """
+                #Activates the checks in the special tables for the wild pokémon data.
+                #[9E][map group][map id]
+                #see also http://hax.iimarck.us/files/scriptingcodes_eng.htm#ZusatzDok3E_66ED
+                """
+                size = 3
+                command["map_group"] = ord(rom[start_address+1])
+                command["map_id"] = ord(rom[start_address+2])
+            elif command_byte == 0xA1: #Hall of Fame code
+                info = "Hall of Fame"
+                long_info = """
+                #Saves and enters HIRO's complete Team in the Hall of Fame.
+                #Shows the credits and restarts the game with HIRO located in New Bark Town.
+                #[9F]
+                """
+                size = 1
+            elif command_byte == 0xA2: #Credits code
+                info = "Credits"
+                long_info = """
+                #Shows the credits and HIRO is located on the Silver mountain plateau.
+                #[A0]
+                """
+                size = 1
+            elif command_byte == 0xA3: #Facing warp
+                info = "Warp-to and set facing direction [Facing (00-03)][Map bank][Map no][X][Y]"
+                long_info = """
+                #Acts like code 0x3C but defines the desired facing of HIRO.
+                #[A1][Facing (00-03)][Map bank][Map no][X][Y]
+                """
+                size = 6
+                command["facing"] = ord(rom[start_address+1])
+                command["map_group"] = ord(rom[start_address+2])
+                command["map_id"] = ord(rom[start_address+3])
+                command["x"] = ord(rom[start_address+4])
+                command["y"] = ord(rom[start_address+5])
+            elif command_byte == 0xA4: #MEMORY code [2b + Bank + xx]
+                info = "Set memX to a string by a pointer [aabb][bank][xx]"
+                long_info = """
+                #MEMORY1, 2 or 3 can directly be filled with a string from
+                #a different rom bank.
+                #[A2][2byte pointer][Bank][00-02 MEMORY]
+                """
+                size = 5
+                command["string_pointer"] = calculate_pointer_from_bytes_at(start_address+1, bank="reversed")
+                command["string_pointer_bank"] = ord(rom[start_address+3])
+                command["memory_id"] = ord(rom[start_address+4])
+            elif command_byte == 0xA5: #Display any location name [xx]
+                info = "Copy the name of a location (by id) to TEMPMEMORY1"
+                long_info = """
+                #By the location number the name of that location is written to TEMPMEMORY1.
+                #[A3][Location no]
+                """
+                size = 2
+                command["location_number"] = ord(rom[start_address+1])
             else:
-                pksv_no_names[command_byte] = [address]
+                size = 1
+                #end = True
+                #raise NotImplementedError, "command byte is " + hex(command_byte) + " at " + hex(offset) + " on map " + str(map_group) + "." + str(map_id)
+                print "dunno what this command is: " + hex(command_byte)
+            long_info = clean_up_long_info(long_info)
+            
+            if command_byte in pksv_crystal.keys():
+                pksv_name = pksv_crystal[command_byte]
+            else:
+                pksv_name = None
+                if command_byte in pksv_no_names.keys():
+                    pksv_no_names[command_byte].append(address)
+                else:
+                    pksv_no_names[command_byte] = [address]
+    
+            if debug:
+                print command_debug_information(command_byte=command_byte, map_group=map_group, map_id=map_id, address=offset, info=info, long_info=long_info, pksv_name=pksv_name)
+            
+            #store the size of the command
+            command["size"] = size
+            #the end address is just offset + size - 1 (because size includes command byte)
+            offset += size - 1
+            #the end address is the last byte belonging to this command
+            command["last_byte_address"] = offset
+            #we also add the size of the command byte to get to the next command
+            offset += 1
+            #add the command into the command list please
+            commands[len(commands.keys())] = command
+    
+        self.commands = commands
+        script_parse_table[original_start_address : offset-1] = self
+        return True
+def parse_script_engine_script_at(address, map_group=None, map_id=None, force=False, debug=True, origin=True):
+    if is_script_already_parsed_at(address) and not force:
+        return script_parse_table[address]
+    return Script(address, map_group=map_group, map_id=map_id, force=force, debug=debug, origin=origin)
 
-        if debug:
-            print command_debug_information(command_byte=command_byte, map_group=map_group, map_id=map_id, address=offset, info=info, long_info=long_info, pksv_name=pksv_name)
-        
-        #store the size of the command
-        command["size"] = size
-        #the end address is just offset + size - 1 (because size includes command byte)
-        offset += size - 1
-        #the end address is the last byte belonging to this command
-        command["last_byte_address"] = offset
-        #we also add the size of the command byte to get to the next command
-        offset += 1
-        #add the command into the command list please
-        commands[len(commands.keys())] = command
-
-    script_parse_table[original_start_address : offset-1] = commands    
-    return commands
-
 def parse_warp_bytes(some_bytes, debug=True):
     """parse some number of warps from the data"""
     assert len(some_bytes) % warp_byte_size == 0, "wrong number of bytes"
@@ -4426,6 +4514,10 @@
         cleaned_name = map_name_cleaner(map_data["name"])
         #set the value in the original dictionary
         map_names[map_group_id][map_id]["label"] = cleaned_name
+
+#### pretty printing ###
+#texts: TextScript.to_asm_at
+#scripts: Script.to_asm_at
 
 #### asm utilities ####
 #these are pulled in from pokered/extras/analyze_incbins.py