Re: 41Z Breakthrough: 4-level Complex Stack Message #15 Posted by 聲gel Martin on 19 Aug 2009, 3:10 a.m., in response to message #14 by 聲gel Martin
I too am leaning towards the full complex stack solution. I *think* I have figured out all the situations where it would come to place, see if you find something missing:
Design Criteria:
1. The complex Buffer has 5 levels, from L0 (for lastZ) to L4 - plus its header. Each level holds 2 registers, thus 11 regs in total, called b0 (header) to b10 (imaginary part of L4).
2. The Mapping with the real stack is as follows:
X=b3, Y=b4, Z=b5, T=b6. L=b1
3. All functions take their input from X,Y (if monadic) or [X,Y,Z,T] if dual. The output is placed also on the stack, no interaction with the buffer during the calculation phase.
4. It's upon the function to save the operand into L0 (LastZ) prior to executing the math, and to synchronize the stack with the complex buffer upon completion.
Once these criteria are defined, we need to properly structure the "Special events", as follows:
A.- ZENTER^.
1. writes (X,Y) into L1 (b3,b4)
2. buffer normal lift: L3->L4; L2->L3; L1->L2
3. synch: writes [b3-b6] to stack [X,Y,Z,T] (this is for consistency with other processes, as it only requires writing (X,Y) into (T,Z).
This is the key point that solves the previous issue: now it doesn't matter what happens to the real stack (like T spilling over) because the complex buffer L2 remains untouched upon execution of ZENTER^. Naturally one must be disciplined and ALWAYS execute ZENTER^ upon complex data input, or otherwise the real stack and the complex buffer will de-synchronize.
B.- LASTZ.
1. buffer long lift: L3->L4; L2->L3; L1->L2; L0->L1
2. synch: writes [b3-b6] to stack [X,Y,Z,T]
C.- ZRDN.
1. saves L1 (b3,b4) into scratch (M,N), keeps Alpha untouched
2. buffer drop: L2->L1; L3->L2; L4->L3
3. writes scratch into L4 (b9,b10)
4. synch: writes [b3-b6] into stack [X,Y,Z,T]
D.- ZR^.
1. saves L4 (b9,b10) into scratch (M,N)
2. buffer normal lift: L3->L4; L2->L3;, L1->L2
3. writes scratch into L1 (b3,b4)
4. synch: writes [b3-b6] into stack [X,Y,Z,T]
E.- ZRCL__.
1. buffer normal lift: L3->L4; L2->L3; L1->L2
2. writes X,Y into L1
3. synch: writes [b3-b6] into stack [X,Y,Z,T]
(done like this for consistency sake, other sequences are also possible)
And here's how these are being used during the execution flow:
I. Monadic Function:
0. Save (X,Y) into LastZ [L0]- (b1,b2)
1. Execute function (all within stack)
2. write X,Y result into buffer L1
3. synch: writes [b3-b6] to stack [X,Y,Z,T] (this is for consistency with other processes, as it's NOT really required if the function was executed right after ZENTER^, but provides more flexibility for quick-access)
II. Dual Function:
0. Save (X,Y) into LastZ [L0] - (b1,b2)
1. Execute function (all within the stack)
2. write X,Y result into buffer L1
3. perform buffer drop: L3->L2; L4->L3
4. synch: writes [b3-b6] to stack [X,Y,Z,T] (this is for consistency with other processes, as it only requires writing L2 (b5,b6) into (Z,T)
So things are getting complex (no pun intended?). Whilst not an easy scenario it's doable just the same - if tedious sometimes. My head is spinning with RAM SELECT and READ/WRIT DATA statements, I'm going to print this out and memorize before continuing with the code writing!
Do you see any other situation missing on the above lists??
Best,
簍
Edited: 19 Aug 2009, 5:45 p.m.
|