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: