From 9a2757d16d63b74a642b513419f305f4da899446 Mon Sep 17 00:00:00 2001 From: Connor Olding Date: Thu, 17 Dec 2015 22:59:32 -0800 Subject: [PATCH] (attempt to) abide to calling conventions i haven't checked if i need double-word alignment --- Lua/README.md | 3 +++ Lua/inject.lua | 12 +++++++----- Lua/inject/crap.asm | 9 ++++----- Lua/inject/lips.lua | 28 +++++++++++++++++----------- 4 files changed, 31 insertions(+), 21 deletions(-) diff --git a/Lua/README.md b/Lua/README.md index 18753b3..7670f35 100644 --- a/Lua/README.md +++ b/Lua/README.md @@ -40,6 +40,9 @@ which produces [a large csv file.][csv] Tests the fastest form of basic movement in Majora's Mask. Run it in the Clock Town Great Fairy's Fountain. +#### inject.lua +Assembles and injects an assembly subroutine into the game. + #### oneshot.lua Instantly gives you all the items in the game, etc. diff --git a/Lua/inject.lua b/Lua/inject.lua index 600d865..62cb5d2 100644 --- a/Lua/inject.lua +++ b/Lua/inject.lua @@ -37,14 +37,16 @@ local ow_before_addr = (ow_before % 0x4000000)*4 local header = ("[overwritten]: 0x%08X\n"):format(ow_before_addr) header = header..[[ - sw ra, -4(sp) + // TODO: optimize for size + // TODO: fix case where overwritten function takes 5+ args + push ra + push a0, a1, a2, a3 bal start - subi sp, sp, 4 + nop + pop a0, a1, a2, a3 jal @overwritten nop - lw ra, 0(sp) - jr - addi sp, sp, 4 + jpop ra start: ]] diff --git a/Lua/inject/crap.asm b/Lua/inject/crap.asm index cb02e33..31d3d21 100644 --- a/Lua/inject/crap.asm +++ b/Lua/inject/crap.asm @@ -24,7 +24,7 @@ [cosf]: 0x80091F40 main: - push ra, a0, s1, s3, s4 + push 4, s1, s3, s4, ra // s1: current actor ptr // s3: current actor type ptr // s4: current actor type index @@ -70,12 +70,11 @@ continue: bne s4, t0, typeloop addi s3, s3, @actorlist_dead_space - jpop ra, a0, s1, s3, s4 + jpop 4, s1, s3, s4, ra process_actor: // args: a0. returns nothing. // TODO: ignore bomb explosions, they share the same type - push r0, ra, s0, s1 - // 0(sp) reserved for sinf/cosf + push 4, s0, s1, ra // s0: result of sin // s1: result of cos lh t0, 0(a0) @@ -128,7 +127,7 @@ process_actor: // args: a0. returns nothing. sw t5, current_rotation process_actor_return: - jpop r0, ra, s0, s1 + jpop 4, s0, s1, ra rotations: .word 0x00000000 // pi*0/6 diff --git a/Lua/inject/lips.lua b/Lua/inject/lips.lua index dc397ba..f650e38 100644 --- a/Lua/inject/lips.lua +++ b/Lua/inject/lips.lua @@ -1034,31 +1034,37 @@ function Parser:instruction() local addi = instructions['ADDI'] local w = instructions[h == 'PUSH' and 'SW' or 'LW'] local jr = instructions['JR'] - local registers = {} + local stack = {} while not self:is_EOL() do - local r = self:register() - table.insert(registers, r) + if self.tt == 'NUM' then + if self.tok < 0 then + self:error("can't push a negative number of spaces") + end + for i=1,self.tok do + table.insert(stack, '') + end + self:advance() + else + table.insert(stack, self:register()) + end if not self:is_EOL() then self:optional_comma() end end - if #registers == 0 then + if #stack == 0 then self:error(h..' requires at least one argument') end - if #registers >= 0x8000/4 then - self:error("that's way too many registers bub") - end local args = {} if h == 'PUSH' then args.rt = 'SP' args.rs = 'SP' - args.immediate = {'NEGATE', {'NUM', #registers*4}} + args.immediate = {'NEGATE', {'NUM', #stack*4}} self:format_out(addi[3], addi[1], args, addi[4], addi[5]) end args.base = 'SP' - for i, r in ipairs(registers) do + for i, r in ipairs(stack) do args.rt = r - if r ~= 'R0' then + if r ~= '' then args.offset = {'NUM', (i - 1)*4} self:format_out(w[3], w[1], args, w[4], w[5]) end @@ -1070,7 +1076,7 @@ function Parser:instruction() if h == 'POP' or h == 'JPOP' then args.rt = 'SP' args.rs = 'SP' - args.immediate = {'NUM', #registers*4} + args.immediate = {'NUM', #stack*4} self:format_out(addi[3], addi[1], args, addi[4], addi[5]) end elseif h == 'NAND' then