Re: A83: asm coded basic routine


[Prev][Next][Index][Thread]

Re: A83: asm coded basic routine




The ultimate problem with it is that any ASM code that revolves around
BASIC variables and ROM calls is bound to be pratically as slow as the
basic version. Further, if you are doing divisions that require
decimals, then there is little room to optimize

> Jacob Guilbeau wrote:
> 
> 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
> 
> 
> 
> 
> 
> 
> 
> 

-- 
Scott "_Wrath_" Dial
wrath@calc.org
ICQ#3608935
Member of TCPA - tcpa.calc.org
__________________________________________
NetZero - Defenders of the Free World
Get your FREE Internet Access and Email at
http://www.netzero.net/download/index.html



Follow-Ups: References: