1
0
Fork 0
mirror of https://github.com/notwa/mm synced 2025-02-05 05:23:22 -08:00

(attempt to) abide to calling conventions

i haven't checked if i need double-word alignment
This commit is contained in:
Connor Olding 2015-12-17 22:59:32 -08:00
parent 7c35d99a9f
commit 9a2757d16d
4 changed files with 31 additions and 21 deletions

View file

@ -40,6 +40,9 @@ which produces [a large csv file.][csv]
Tests the fastest form of basic movement in Majora's Mask. Tests the fastest form of basic movement in Majora's Mask.
Run it in the Clock Town Great Fairy's Fountain. Run it in the Clock Town Great Fairy's Fountain.
#### inject.lua
Assembles and injects an assembly subroutine into the game.
#### oneshot.lua #### oneshot.lua
Instantly gives you all the items in the game, etc. Instantly gives you all the items in the game, etc.

View file

@ -37,14 +37,16 @@ local ow_before_addr = (ow_before % 0x4000000)*4
local header = ("[overwritten]: 0x%08X\n"):format(ow_before_addr) local header = ("[overwritten]: 0x%08X\n"):format(ow_before_addr)
header = header..[[ 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 bal start
subi sp, sp, 4 nop
pop a0, a1, a2, a3
jal @overwritten jal @overwritten
nop nop
lw ra, 0(sp) jpop ra
jr
addi sp, sp, 4
start: start:
]] ]]

View file

@ -24,7 +24,7 @@
[cosf]: 0x80091F40 [cosf]: 0x80091F40
main: main:
push ra, a0, s1, s3, s4 push 4, s1, s3, s4, ra
// s1: current actor ptr // s1: current actor ptr
// s3: current actor type ptr // s3: current actor type ptr
// s4: current actor type index // s4: current actor type index
@ -70,12 +70,11 @@ continue:
bne s4, t0, typeloop bne s4, t0, typeloop
addi s3, s3, @actorlist_dead_space addi s3, s3, @actorlist_dead_space
jpop ra, a0, s1, s3, s4 jpop 4, s1, s3, s4, ra
process_actor: // args: a0. returns nothing. process_actor: // args: a0. returns nothing.
// TODO: ignore bomb explosions, they share the same type // TODO: ignore bomb explosions, they share the same type
push r0, ra, s0, s1 push 4, s0, s1, ra
// 0(sp) reserved for sinf/cosf
// s0: result of sin // s0: result of sin
// s1: result of cos // s1: result of cos
lh t0, 0(a0) lh t0, 0(a0)
@ -128,7 +127,7 @@ process_actor: // args: a0. returns nothing.
sw t5, current_rotation sw t5, current_rotation
process_actor_return: process_actor_return:
jpop r0, ra, s0, s1 jpop 4, s0, s1, ra
rotations: rotations:
.word 0x00000000 // pi*0/6 .word 0x00000000 // pi*0/6

View file

@ -1034,31 +1034,37 @@ function Parser:instruction()
local addi = instructions['ADDI'] local addi = instructions['ADDI']
local w = instructions[h == 'PUSH' and 'SW' or 'LW'] local w = instructions[h == 'PUSH' and 'SW' or 'LW']
local jr = instructions['JR'] local jr = instructions['JR']
local registers = {} local stack = {}
while not self:is_EOL() do while not self:is_EOL() do
local r = self:register() if self.tt == 'NUM' then
table.insert(registers, r) 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 if not self:is_EOL() then
self:optional_comma() self:optional_comma()
end end
end end
if #registers == 0 then if #stack == 0 then
self:error(h..' requires at least one argument') self:error(h..' requires at least one argument')
end end
if #registers >= 0x8000/4 then
self:error("that's way too many registers bub")
end
local args = {} local args = {}
if h == 'PUSH' then if h == 'PUSH' then
args.rt = 'SP' args.rt = 'SP'
args.rs = '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]) self:format_out(addi[3], addi[1], args, addi[4], addi[5])
end end
args.base = 'SP' args.base = 'SP'
for i, r in ipairs(registers) do for i, r in ipairs(stack) do
args.rt = r args.rt = r
if r ~= 'R0' then if r ~= '' then
args.offset = {'NUM', (i - 1)*4} args.offset = {'NUM', (i - 1)*4}
self:format_out(w[3], w[1], args, w[4], w[5]) self:format_out(w[3], w[1], args, w[4], w[5])
end end
@ -1070,7 +1076,7 @@ function Parser:instruction()
if h == 'POP' or h == 'JPOP' then if h == 'POP' or h == 'JPOP' then
args.rt = 'SP' args.rt = 'SP'
args.rs = '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]) self:format_out(addi[3], addi[1], args, addi[4], addi[5])
end end
elseif h == 'NAND' then elseif h == 'NAND' then