A83: asm coded basic routine
[Prev][Next][Index][Thread]
A83: asm coded basic routine
Ok guys, here's my problem:
I am trying to optimize this basic routine by
converting it to ASM. The commands were simple enough, I just can't seem
to get the loop going. Anyway, here is my basic code that I am trying to
port:
Lbl P
L+H*Y1 -> L
X+.5H -> X
M+H*Y1
-> M
X+.5H -> X
IS>(I,N)
Goto P
and here is the asm code i wrote with comments
detailing my train of thought:
.NOLIST
#define end .end
#define END
.end
#define equ .equ
#define EQU .equ
#include
"ti83asm.inc"
#include "tokens.inc"
.LIST
;----Used in multiplying Y1 by X
_errundefined .equ 467Bh
equobj .equ
03h
_parseinp equ 4E8Ch
.org 9327h
;-----Stores Basic Variable "H" in
Op1.
call
_zerooop1
ld
hl,op1+1
ld
(hl),'H'
call
_rclvarsym
;----Puts Op1 into
op2.
call _op1toop2
;----Multiplies Y1 times basic variable "X"
and
;----Stores that into
Op1.
call
_zerooop1
ld
hl,op1
ld
(hl),equobj
inc
hl
ld
(hl),tvarequ
inc
hl
ld
(hl),10h
call
_chkfindsym
jp
c,_errundefined
call
_parseinp
;----After Y1(X) is stored into Op1, Im going to
multiply that by 'H'
;----Which is still stored in Op2. _FPMULT
multiplies Op1 by Op2
;----And stores that into
Op1.
call
_fpmult
;----Now Im going to put the result of
multiplying
;----Y1(X)*H into
Op2.
call
_op1toop2
;----Here, Im putting basic variable 'L' into
Op1. Notice its the
;----Same code as when I stored
'H'.
call
_zerooop1
ld
hl,op1+1
ld
(hl),'L'
call
_rclvarsym
;----Now I'm going to want to add 'L'('L' is in Op1
now) to Y1(X)*H (which is in
Op2).
call
_fpadd
;----This finishes up the first part of the line
L+H*Y1 -> L except
;----I haven't stored the result to the basic variable
'L' yet.
;----Im sure there is a more effecient way of doing this, but this
is what I did. :-)
;----The following code stores L+H*Y1 into
L.
call
_pushrealo1
call
_zerooop1
ld
hl,'L'
ld
(op1+1),hl
call
_stoother
;----Now I start the second Line by getting 'H' and
putting that into Op1.
call
_zerooop1
ld
hl,op1+1
ld
(hl),'H'
call
_rclvarsym
;----Now I multiply that by
.5
call _timespt5
;----And put the result of that into
Op2.
call _op1toop2
;----And because TI loves us so much, they have
included
;----a way for us to retreive basic variable 'X' and
'Y'
;----without all that other clunky coding.
;----And here it
is...
call _rclx
;----I know, you were mesmerized.
;----Following the code of my basic program, I must
now
;----add X to the result of multiplying H and .5 (Which is in
Op2)
call _fpadd
;----Now I will store that to
X...
call _stox
;----And am now complete with my second line, X+.5H
-> X.
;----Now with M+H*Y1 -> M I'm going to do the
exact same thing I did above
;----with 'L' except replace the 'L' with
'M'. In fact, I cut and paste.
;----Although this time I noticed that i
am getting the result of Y1*X first,
;----and then grabbing H. I wonder
is this makes a difference...
;----Grabbing the result of Y1 times
X.
call
_zerooop1
ld
hl,op1
ld
(hl),equobj
inc
hl
ld
(hl),tvarequ
inc
hl
ld
(hl),10h
call
_chkfindsym
jp
c,_errundefined
call
_parseinp
;----Putting Y1*X into
Op2
call _op1toop2
;----Now I grab 'H' from
basic.
call
_zerooop1
ld
hl,op1+1
ld
(hl),'H'
call
_rclvarsym
;----And multiply that by
Y1*X.
call _fpmult
;----And I put THAT result into
Op2.
call _op1toop2
;----And grab 'M' from
basic.
call _zerooop1
ld
hl,op1+1
ld
(hl),'M'
call
_rclvarsym
;----And Add that to the result of Y1(X)*H (which
is in Op2).
call _fpadd
;----I am now complete with the third line of basic
code, M+H*Y1.
;----All I need to do now is store that into
'M'.
call
_pushrealo1
call
_zerooop1
ld
hl,'M'
ld
(op1+1),hl
call
_stoother
;----And Voila!
;----I'm almost done. All I need to do for
the final computation line
;----is the same thing I've done above. The
exact same thing.
;----Grab 'H' from
basic.
call _zerooop1
ld hl,op1+1
ld
(hl),'H'
call
_rclvarsym
;----Multiply by
.5
call _timespt5
;----Put in
Op2.
call _op1toop2
;----Put this in in case i needed to clear
Op1. Was just curious.
;----May be a waste of clock cycles...Oh
well...
call _zerooop1
;----Recalls 'X' into
Op1.
call _rclx
;----Adds Op1 and Op2 or X +
.5H
call _fpadd
;----Stores that back into
'X'
call _stox
;----And I'm done. This code took a while to
understand and I think I've finally gotten the hang of it.
ret
.end
Ok...here's the thing. This code is taken
from a program that finds the reimann sum for estimating the derivative of a
function. The only problem with it is that it is slow as hell. I'm
sure you ASM dudes are wondering why in the hell I called to and from basic
variables so much. Well, while I was testing, I determined that Op4-Op6
didnt retain their values that I put into them very long. Anyway....I was
wondering if any of you guys might be able to help me out in putting a Loop like
the IS>(I,N) in the basic part. The way that works is that "I" is the
counter that is initialzed to 1 and IS Increments it and then executes the
command Goto P to jump to P. It skips the Goto P when "I" becomes greater
than "N", a user inputed number of reimann sum divisions. I need this
number to be <= 100,000. The point of this program is to show the
obvious speed advantage when using ASM and I hate waiting for basic to give me a
result when I need over 1,000 divisions. It's been reported that the basic
division for 100,000 is over 2 hours. Thats hella slow. I would
greatly apreciate anything you guys can suggest, including optimizations, and I
give permission for anybody to use this code for their own purposes without
giving me credit. Hell, most of this code was lifted right out of ASM
guru. ;-)
Thank you very much.
Jake
Follow-Ups: