Author 
Message 

mortdiggiddy
Newbie
Joined: 17 May 2008 Posts: 17

Posted: 17 May 2008 03:29:53 pm Post subject: 


I am new to z80. I created a program in BASIC to plot the root locus of a transfer function, but the algorithm to find the roots of a ndegree polynomial is slow (it's basic, duh). I need to be able to get a function from the user input from a getkey loop or w/e, then translate this to a y= function (using rom calls I assume to create an equation), and then have the ability to vary the value of the independent variable x and have the equation solved for that value. The algorithm to solve for the roots of a polynomial needs this operation.
I'm not sure if this is a dumb question, or if it isn't possible. So far in every tutorial or system routine explanation, I have only seen how to create a new equation, not actually how to make the equation's contents what you need it to be.
Thanks for the help.
Last edited by Guest on 17 May 2008 03:50:14 pm; edited 1 time in total 

Back to top 


DarkerLine ceci n'est pas une 
Super Elite (Last Title)
Joined: 04 Nov 2003 Posts: 8328

Posted: 17 May 2008 04:19:47 pm Post subject: 


What's wrong with using Basic to store to a Y= equation? You can do this by storing a string to it:
Input "Eqn?",Str1
Str1→Y1
Doing this in assembly is more complicated. Equations are internally stored as strings, which themselves are made up of tokens. If you just had a fixed equation to create, you might do something like this:
ld hl, Y1Name
rst 20h ; _Mov9ToOP1
ld hl, EquationEnd  Equation
bcall(_CreateEqu)
inc de
inc de
ld hl, Equation
ld bc, EquationEnd  Equation
ldir
ret
Y1Name:
.db EquObj,tVarEqu,tY1,0,0
Equation:
.db tX,tSqr,tAdd,t2,tX,tAdd,t1
EquationEnd:
If you wanted the user to input an equation, you'd need to be able to convert keypresses to tokens, and possibly simulate builtin menus as well... There's some sort of bcall for this maybe, but I don't remember it... it's just ugly. Some things Basic just does better.
Last edited by Guest on 02 Aug 2010 02:05:45 am; edited 1 time in total 

Back to top 


mortdiggiddy
Newbie
Joined: 17 May 2008 Posts: 17

Posted: 17 May 2008 04:35:48 pm Post subject: 


BASIC for input of equations would be way easier yeah. Is it possible to use BASIC commands like input and prompt imbedded in a z80 file? Once the Y1 function is saved, how do I access it and get the output of it evaluated for a value of x? 

Back to top 


magicdanw pcGuru()
Calc Guru
Joined: 14 Feb 2007 Posts: 1110

Posted: 17 May 2008 07:49:58 pm Post subject: 


One way to get input from the user is to make a basic program with the Input command in it, and then run the basic program using assembly code. This is done with the ParseInp bcall, which will run the basic program named in OP1. After that, you can use the bcall UnOpExec to run the expr( command, which will return the value of the equation at X. Finally, to change the value of X, you can write the number (in Real Floating Point number format, which is how the Os stores numbers internally) to X, which you can find using FindSym.
Hope that helped. If you have any questions (I suspect you will have a couple) just ask! 

Back to top 


brandonw
Advanced Member
Joined: 12 Jan 2007 Posts: 455

Posted: 17 May 2008 07:56:44 pm Post subject: 


I dug up some old code from that calcg.org RPN contest which lets you input a string/equation from assembly:
Code:
.nolist
#include "ti83plus.inc"
.list
.org userMem2
.db 0BBh,6Dh
programStart:
ld hl,savesscreen
ld bc,768
bcall(_MemClear)
ld hl,rpnStart
ld de,appBackUpScreen
ld bc,rpnEndrpnStart
ldir
ld (ramCode),bc
ld hl,promptString
ld de,ioPrompt
bcall(_strcopy)
jp appBackUpScreen
promptString:
.db "Enter expr.: ",0
rpnStart:
ld hl,userMem
ld de,programEndprogramStart
bcall(_DelMem)
ld b,(iy+9)
ld c,(iy+1Ch)
push bc
res 6,(iy+1Ch)
set 7,(iy+9)
bcall(4E5Eh)
pop bc
res 4,b
ld (iy+9),b
ld (iy+1Ch),c
ld hl,2Dh
ld (OP1+1),hl
rst 10h
ex de,hl
ld c,(hl)
inc hl
ld b,(hl)
inc hl
ld de,savesscreen
push de
ldir
set cmdVirgin,(iy+cmdFlags)
parseLoopRestart:
pop hl
ld de,appData
ld bc,0
parseLoop:
ld a,(hl)
or a
jp z,parseDonerpnStart+appBackUpScreen
inc hl
cp 29h
jr z,numberDone
cp 82h
jr nz,notMultiply
inc hl
push hl
call getArgumentsrpnStart+appBackUpScreen
bcall(_FPMult)
pushParseLoopRestart:
call addNumberrpnStart+appBackUpScreen
jr parseLoopRestart
notMultiply:
cp 83h
jr nz,notDivide
inc hl
push hl
call getArgumentsrpnStart+appBackUpScreen
bcall(_FPDiv)
jr pushParseLoopRestart
notDivide:
cp 70h
jr nz,notAdd
inc hl
push hl
call getArgumentsrpnStart+appBackUpScreen
bcall(_FPAdd)
jr pushParseLoopRestart
notAdd:
cp 71h
jr nz,parseLoopContinue
inc hl
push hl
call getArgumentsrpnStart+appBackUpScreen
bcall(_FPSub)
jr pushParseLoopRestart
parseLoopContinue:
ld (de),a
inc de
inc bc
jr parseLoop
numberDone:
push hl
push bc
inc bc
inc bc
ld h,b
ld l,c
bcall(432Dh);_CreateTempEqu
inc de
inc de
xor a
ld (de),a
inc de
ld (de),a
inc de
ld hl,appData
pop bc
ldir
bcall(_OP4ToOP1)
bcall(_ParseInp)
call addNumberrpnStart+appBackUpScreen
jr parseLoopRestart
parseDone:
bit cmdVirgin,(iy+cmdFlags)
jr nz,exitProgram
bcall(_newLine)
call removeNumberrpnStart+appBackUpScreen
ld a,6
bcall(_FormReal)
ld hl,OP3
bcall(_PutS)
exitProgram:
bcall(_newLine)
bjump(_JForceCmdNoChar)
getArguments:
res cmdVirgin,(iy+cmdFlags)
call removeNumberrpnStart+appBackUpScreen
call removeNumberrpnStart+appBackUpScreen
ret
addNumber:
bcall(_PushRealO1)
ld hl,ramCode
inc (hl)
ret
removeNumber:
ld a,(ramCode)
dec a
ld (ramCode),a
inc a
jr z,throwError
bcall(_popRealO1)
ret
throwError:
bcall(_CleanAll)
ld a,E_Undefined & 7Fh
bjump(_JError)
rpnEnd:
programEnd:
.end
end
A little ugly, but BCALL 4E5Eh is (what I call) _GetStringInput. Just throwing it out there in case it's of some use.
Last edited by Guest on 18 May 2008 01:58:38 am; edited 1 time in total 

Back to top 


magicdanw pcGuru()
Calc Guru
Joined: 14 Feb 2007 Posts: 1110

Posted: 17 May 2008 08:35:09 pm Post subject: 


**Eyes glaze over** Dear Lord!!!!! 

Back to top 


thornahawk μολών λαβέ
Active Member
Joined: 27 Mar 2005 Posts: 569

Posted: 17 May 2008 11:14:15 pm Post subject: 


[OFFTOPIC]
What algorithm are you using to solve for polynomial roots? As I recall, this is one particular application where you do need all the roots of a polynomial.
thornahawk 

Back to top 


mortdiggiddy
Newbie
Joined: 17 May 2008 Posts: 17

Posted: 18 May 2008 12:12:37 am Post subject: 


http://en.wikipedia.org/wiki/DurandKerner_method
That is basically the algorithm, and encoded its actually a really simple double for() loop. Translate this BASIC code to assembly is what I am trying to do
~A is just an arbitrary variable to count the for() loop, same with B
~D is the degree of the polynomial, ex) 3x^3 + 2x^2 + 5x + 10 is degree 3
~two temp Lists are created, LROOT and LTEST. LROOT contains the new values for the roots of the polynomial, LTEST contains the "old" roots that you are comparing LROOT to to see if there was any change.
~R is the user set round, for accuracy, once you get beyond degree 4 polynomials, you can pretty much set this to zero, because getting 5+ roots to not change from one iteration to the next already ensures pretty good accuracy.
;
;Initialize the roots at a "guess" value, can be virtually anything as long as ;x=a+bi where x is not a root of 1
:0.9 + 0.9i > X
:For(A, 1, D, 1)
:X^(A1)>LROOT(A)
:0>LTEST(A)
:end
:
:
:
:1>T
:While round(Real(LROOTLTEST), R) != 0
:LROOT>LTEST
:For(A, 1, D, 1)
:For(B, 1, D, 1)
:If A!=B
:T*(LROOT(A)LROOT(B))>T
:end
:LROOT(A)>X
:LROOT(A)  Y1(X)/T>LROOT(A)
:end
:end
Last edited by Guest on 18 May 2008 12:12:59 am; edited 1 time in total 

Back to top 


thornahawk μολών λαβέ
Active Member
Joined: 27 Mar 2005 Posts: 569

Posted: 18 May 2008 02:50:17 am Post subject: 


You might want to look into the EhrlichAberth method; it performs similarly to DurandKerner and oftentimes yields more accurate answers in less iterations, only at the expense of having to evaluate the polynomial's derivative along with the polynomial itself. I had written an implementation of it a while back. The wrinkle in mine is that I had chosen to have the polynomial input as a list of coefficients rather than as an explicit Y= function. You will have to adapt the code to your purposes if you're interested.
There's a pretty wide literature on "simultaneous methods", as they are called. I'll be happy to answer questions.
thornahawk 

Back to top 


mortdiggiddy
Newbie
Joined: 17 May 2008 Posts: 17

Posted: 18 May 2008 07:00:40 pm Post subject: 


One quick question about complex floating point math.
If I have multiple complex FP's on the FP stack, when I do an operation that uses OP1/OP2 with FPS1/FPST, does the stack move down one so that the the next complex FP's that WERE on the stack below FPS1/FPST move up? 

Back to top 


DarkerLine ceci n'est pas une 
Super Elite (Last Title)
Joined: 04 Nov 2003 Posts: 8328

Posted: 18 May 2008 08:15:35 pm Post subject: 


That sort of question could be resolved very simply by, I don't know, trying it to see what happens? 

Back to top 


