Thread: Development: Lua? In MY emulator?
View Single Post
  #2    
Old February 8th, 2013 (1:44 PM). Edited February 8th, 2013 by knizz.
knizz's Avatar
knizz knizz is offline
     
    Join Date: Aug 2007
    Posts: 192
    UPDATE: The building process for linux users should be fully automated now.

    Here's a test-file you can use with my emulator. Put it in the top folder of the project and name it… "pokemon.lua" maybe. Launch the emulator with 'vbam -l firered.gba' in the top folder, press F11, type 'require "pokemon"'. Resume emulation with Ctrl+D. You should see lots of debug output now. (PROFIT!)
    Code:
    -- Usage:
    --  require "pokemon"
    --  Ctrl+D
    
    require "bkpt"
    bit = require "bit"
    stack = require "stack"
    stack.over = {}
    
    mute_c3 = false
    
    function pwrite(x)
        io.write(string.format("%-80s", x))
        printtrace()
    end
    
    function c3_init_enter()
        print("\n======== RESET C3 ========\n")
        mute_c3 = true
    end
    
    function c3_init_leave()
        mute_c3 = false
    end
    
    function c3watch_trigger(self, a, b, c)
        if mute_c3 then return end
        local space = ""
        for i=1,self.id do space = space.."            " end
        if a == 0 then
            pwrite(space..string.format("#%02x ", self.id) .. ref(c))
        elseif a == 4 then
            pwrite(space..string.format("#%02x ", self.id) .. (c==1 and "ON" or "OFF"))
        end
    end
    
    function dp01watch_trigger(self, a, b, c)
        local space = ""
        for i=1,self.id do space = space.."       " end
        pwrite("DP01 ==== "..space..ref(c))
    end
    
    in_script = false
    function script_enter() in_script = true  end
    function script_leave() in_script = false end
    function script_env_trigger(self, a, b, c)
        -- a = offset
        -- b = old value
        -- c = new value
        if a >= 0x74 then
            return
        end
        if a == 0x5C and c ~= 0x0815F9B4 then
            print("!!!!!!!!!!!!!!!!!!!!!!!!!!!")
            print(string.format("New script command table @ %08x", c))
        end
        if not in_script then
            print(string.format("untracked change 0x%08x+%02x %x->%x", self.start, a, b, c))
            printtrace()
        end
    end
    function script_desc()
        local p = gba.reg(4)
        return string.format("scriptenv %08x @ %08x ", p, gba.mem32(p+8))
    end
    function script_cmd()
        print(script_desc().."cmd: "..ref(gba.reg(1)))
    end
    function script_env_init()
        in_script = true
        pwrite(string.format("scriptenv %08x @ reset", gba.reg(4)))
    end
    function script_status_normal()
        in_script = true
        pwrite(string.format("scriptenv %08x @ %08x LAUNCH", gba.reg(0), gba.reg(1)))
    end
    function oamt_spawn_from_uns_2()
        pwrite(string.format("OAMt from UNS 2 %08x", gba.reg(0)))
    end
    function oamt_spawn_from_uns_1()
        pwrite(string.format("OAMt from UNS 1 %08x", gba.reg(0)))
    end
    
    -- -- -- -- -- -- -- --
    
    function watch_array(start, count, size, trigger)
        for i=0,count do
            local nw = {}
            nw.id = i
            nw.start = start + size*i
            nw.stop =  start + size*(i+1)
            nw.trigger = trigger
            table.insert(watch, nw)
        end
        gba.oldapi("bpw", string.format("0x%08x", start), string.format("%d", count*size))
    end
    
    function watch_simple(pos, size, msg)
        function pp(self, a, b, c)
            pwrite(string.format("%s: %08x+%x: ", msg, self.start, a)..ref(b).." -> "..ref(c))
        end
        local nw = {}
        nw.start = pos
        nw.stop = pos + size
        nw.trigger = pp
        table.insert(watch, nw)
        gba.oldapi("bpw", string.format("0x%08x", pos), string.format("%d", size))
    end
    
    function regmodpoint(addr, reg, value)
        function modder()
            gba.reg(reg, value)
        end
        table.insert(bkpts.inactive, addr)
        bkpts.callback[addr] = modder
    end
    
    -- -- -- -- -- -- -- --
    
    function install()
        bkpts:add(0x080773BC, c3_init_enter)
        bkpts:add(0x0807740C, c3_init_leave)
        bkpts:add(0x08069804, script_enter)
        bkpts:add(0x0806986E, script_cmd)
        bkpts:add(0x0806987C, script_leave)
        bkpts:add(0x080697AC, script_env_init)
        bkpts:add(0x080697E2, script_leave)
        bkpts:add(0x080697E8, script_status_normal)
        bkpts:add(0x080697F0, script_leave)
        bkpts:add(0x08006F8C, oamt_spawn_from_uns_1)
        bkpts:add(0x08006FE0, oamt_spawn_from_uns_2)
    
        watch_array(0x03005090, 16, 0x28, c3watch_trigger)
        watch_array(0x03000eb0,  2, 0x78, script_env_trigger)
        watch_array(0x03004FE0, 4, 4, dp01watch_trigger)
        watch_simple(0x03005020, 4, "map loader")
        -- watch_simple(0x030030F0, 8)
        -- watch_simple(0x02023D74, 4)
        -- watch_simple(0x03004F84, 4)
    
        add_tracepoint(0x08035AC0, "                               ------------AC0", 1)
        -- add_tracepoint(0x0800D8B0, "load dp01 buffer", 1)
        -- add_tracepoint(0x08014068, "", 0)
        -- add_tracepoint(0x08012408, "c1_battle_dp01_bx_r0", 0)
    
        bkpts:enable()
    
        -- You probably don't have this file.
        -- loadnames("firered.map")
    end
    
    -- -- -- -- -- -- -- --
    
    names = {}
    
    function ref(addr)
        local addr = bit.band(addr, bit.bnot(1))
        return names[addr] or string.format("%08x", addr)
    end
    
    function loadnames(fname)
        for line in io.lines(fname) do
            k, v = string.match(line, ":(%x+)       (.+)")
            if k ~= nil then
                names[tonumber(k, 16)+0x08000000] = v
            end
        end
    end
    
    -- -- -- -- -- -- -- --
    
    function introskipper()
        gba.mem32(0x080EC5D0, 0x0800C301)
        gba.mem32(0x0800C4C4, 0x08056645)
        gba.mem32(0x080EC5D0, 0x0800C301)
        gba.mem32(0x0800C4C4, 0x08056645) -- Player Name: Kamon
        gba.mem32(0x08054A68, 0x68204C3C)
        gba.mem32(0x08054A6C, 0xE0014900)
        gba.mem32(0x08054A70, 0x081C5797)
        gba.mem16(0x08054A7E, 0x4E34)
        gba.mem16(0x08054B3A, 0x0000)
        gba.mem16(0x08054B3C, 0x0000)
    end
    
    -- -- -- -- -- -- -- --
    
    install()
    introskipper()
    I can't really explain all of it right now. I hope you can figure it out from the lua-files.
    __________________
    Firered IDA 6.6 DB: https://www.dropbox.com/s/d856o3pyndyr5sr/firered.idb
    VBA-M with lua scripting support
    Reply With Quote