For a while I've been trying to implement
call
/
ret
macros in Redcode so I can call subroutines. The obvious solution is as follows and doesn't work correctly:
; this code is buggy
stack dat 0
call equ mov #2-return, <stack
equ jmp
ret equ jmp return
return mov.b >stack, #0
jmp @return
Unfortunately, this only works for forward calls. The address offset is out by 1 for reverse calls and I can't find a simple fix. I've tried the following solutions, but I'm not particularly happy with any of them:
- adding a
nop
to the top of all subroutines (extra code) - using a macro to automatically adjust the address, e.g.
call subroutine adjust
(ugly) - adjusting the address the first time it is executed (extra code, slower)
Can you suggest a better solution?
3 comments:
The only solution i can find is to fix the value in the 'call' line.
;redcode
;name call/ret
;author Neo
;assert 1
call equ mov.ab #3-stack,<stack
equ jmp
ret equ add.ba stack,1
equ jmp @stack,>stack
ORG main
stack: dat 0,0
su1: nop 1,1
ret
;main code
main: call su1+(su1<0)
call su2+(su2<0)
jmp 0,0
su2: nop 0,0
ret
end
It's uncomfortable, but at least you don't need extra code.
Hi Neo,
Your solution is one of the best I've seen. I implemented something similar, but using a macro to adjust the value.
I'm sure there's a better solution waiting to be discovered.
John
PS - your return code doesn't always work if there's other items on the stack.
org start
stack dat 0
; -------------------------------------
call equ mov #2-return, <stack
equ jmp (a=
fix equ )+(a<0)
ret equ jmp return
return mov.b >stack, #0
jmp @return
; -------------------------------------
for 3
dat 0,0
rof
r1 ret
for 3
dat 0,0
rof
start call r1 fix
call r2 fix
jmp 0
for 3
dat 0,0
rof
r2 ret
Uh, i didn't notice that bug in my code.
"equ jmp (a=
fix equ )+(a>0)"
I didn't know it was possible to let those variable asignement lines unfinished, very neat!
Post a Comment