PROGRAM:A
:"<any two-byte token XX00>":prgmB:!
PROGRAM:B
:{0→u(nMin)
Run prgmA. I have no explanation for this. AFAIK, it works across all versions.
Just confirmed this on my 84+SE ROM in WabbitEmu. Weird - any theories?
"{0→" coupled with that particular variable (or its v/w brethren) is the culprit; it appears to cause the interpreter to pop into the wrong location. I'd be happy if someone who is knowledgeable about the parser would take a look at this.
It also works with any other paired delimiter (parentheses, braces, brackets)
Deep Thought wrote:
It also works with any other paired delimiter (parentheses, braces, brackets)
...What are you talking about?
I meant the first line of prgmA. (Though I guess you already said that the problem is in the {0→u(nMin) line.)
Well, replacing the second quote with anything but a quote will have the rest of the line served as a string, of course. But the point of the demonstration is that the second one of prgmA is being read twice. What ought to happen is that after the called program terminates, execution should resume at somewhere about the prgm token, but certainly not behind it. Let the next post please offer something insightful.
I don't know what the actual cause is, but here's what I do know.
1. This glitch seems to restart the basic parser. It stops loops and removes all callback programs. (This could be a sweet hack)
2. The glitch blows 9 bytes in the FPS per use. I'm not sure where they are used, but I have pulled an Error:Memory using nothing but this glitch.
I'll try to look more into this later, but honestly, breaking For loops might have some serious uses. (Though I'm sure it wastes a lot of memory)
How did you discover this bug?
I legitimately wanted to use {0→u(nMin) in the middle of a program, and soon wondered why it wasn't letting me colon-chain any expressions past that prgm call on the homescreen, e.g., 1→X:prgmA0:Ans² wouldn't get to the Ans² despite the lack of a Return/Stop in the program. So that {0→u(nMin) could appear anywhere in prgmB, and the curio will persist as long as the interpreter is allowed to fall through the final line of the program [EDIT: or hits a Return beforehand].
Related:
Code: :{0}→u(nMin)
:seq(X²,X,1,1
As a program, this works fine. But if you replace the ² with an explicit ^2, you get an ERR:UNDEFINED, and 2:Goto returns to the home screen, indicating a problem with whatever underlying routine seq( uses.
It's a bug in the BCALL _StoOther. It doesn't remove the value from the floating-point stack when you're storing to the following variables: u(nMin), v(nMin), w(nMin), Zu(nMin), Zv(nMin), and Zw(nMin). With the FPS messed up, subprograms and loops will behave very erratically afterward.
I have no idea why, but it's a serious bug and it's kind of amazing no one's ever found it before. TI should probably be told.
I know this post is over three years old, but some of the results I'm getting confuse me. Here are the results from my test programs on an 84+, OS version 2.55. Matrix [A] has been set to [[1]].
Code: PROGRAM:A
[A]:prgmB:!
PROGRAM:B
{42}->u(nMin)
----
prgmA
{42}
When I change prgmB to the following, the results are as follows:
Code: {42}->u(nMin)
Disp 1337
----
1337
1337
Done
{42}->u(nMin)
1337
----
1337
Disp Ans
{42}->u(nMin)
1337:: ;suppress auto-Disp Ans
----
[[1]]
1337
Done
I know from these tests that prgmB is being executed a second time, along with some of the code from prgmA, but I don't understand this (prgmA and prgmB are the same as immediately above):
Code: 1:prgmA
[[1]]
ERR:SYNTAX (points to the "!")
"??":prgmA
[[1]]
Done
(((1:prgmA
[[1]]
Done
((1:prgmA
[[1]]
ERR:SYNTAX (same place)
(42:prgmA
[[1]]
ERR:SYNTAX (same place)
(42):prgmA
[[1]]
Done
123456789123456789:prgmA
[[1]]
Done
Y₁Y₁:prgmA
[[1]]
Done
Y₁1:prgmA
[[1]]
ERR:SYNTAX (same place)
It looks like if there are less than four bytes (not tokens) behind prgmA, it throws an error, and either way prgmB is only executed once!
* Could someone enlighten me of the reason behind this last behavior?
* Has anyone found an interesing way to use this bug?
EDIT: Okay, what the hell?
Code: ::::prgmA
{1.405006118E51}
That value is 42 factorial. When I replace the ! at the end of prgmA with ², I get 42²=1764. When I replace the 42 in prgmB with a different number, it gives me the factorial or square of that. When I replace the ! with *8, I get 42*8=336.
After further experimenting, I have found a way to archive and unarchive programs within other programs:
Code: PROGRAM:A
prgmB
UnArchive prgmC
prgmC
Archive prgmC
PROGRAM:B
{0->u(nMin)
PROGRAM:C
ClrHome
1->X
1->Y
Repeat K=45
Repeat Ans
;[code to move character around screen], yada yada yada
Output(Y,X,"π
End
Call prgmA from the homescreen, and... it works! From prgmA you can do anything you normally do in the homescreen, and in prgmC you can run any program. It may be possible to do this without a third program; if I find a way I'll post it.
Well that's....an interesting development.
Wow, that is actually very interesting. I have no clue what is up.
That's an exceptionally interesting development. Since I have zero free time (and from what I've heard, BrandonW does as well due to an upcoming conference deadline), I hope one of the other ASM-savvy members in the community could confirm how exactly this works.
Weregoose wrote:
Code: :{0}→u(nMin)
:seq(X²,X,1,1
As a program, this works fine. But if you replace the ² with an explicit ^2, you get an ERR:UNDEFINED, and 2:Goto returns to the home screen, indicating a problem with whatever underlying routine seq( uses.
The bug is present on the TI-83 also (TI-82 lacks u(n-1) and related). However, the behavior is different; instead of throwing an error, a lot of garbage is outputted in a list.
Lirtosiast's examples, tested on ROM 1.0200, give the same results for the first part of the posf. In the second part, the last two examples throw ERR:INVALID before prgmA is executed.
My TI-83 Plus, OS 1.19, doesn't seem to exhibit this behavior in Weregoose's example, but Lirtosiast's examples produce the same output as the 84+.
On the TI-84 Plus CE, OS 5.0.1, I get a Syntax Error at the "!". When I remove it, I just get {42} as the value displayed when the nested programs end, which makes sense.
CVSoft, you didn't initialize Y₁ before you ran the program.
I have not found a way to use only two programs; this is the closest I've come:
Code: PROGRAM:A
{0->u(nMin)
If π=X
Return
π→X
prgmA
DelVar X
UnArchive prgmC
prgmC
Archive prgmC
:::::::::::::::::::::prgmA ;16 colons
;runs prgmC correctly
It seems like the parser pops into the place in prgmA corresponding to where the last homescreen token of the command that calls prgmA is. For example, if there are 16 colons it will start running at the 17th byte. There are eight letters possible in a program name, so if someone figures out a way to get homescreen mode in the first 8 bytes of prgmA, we'll have solved it. Note that no program tokens are valid in homescreen mode, so we can't just move everything to the end.
Again, it would be helpful for someone to test this on both color calculators.
EDIT: This works without the colons! Again, program C can be anything.
Code: PROGRAM:AAAAAAAA
{0->u(nMin)
"..":If π=X:Return:For(X,π,0:End:prgmAAAAAAAA
DelVar X
UnArchive prgmC
prgmC
Archive prgmC
The two dots inside the string are filler characters, which are required because the program name is 8 characters long. For a seven- or six-letter program name, there should be one or zero filler characters instead.
Note: When a program tries to archive itself, it runs, but if it also tries to unarchive itself it throws an ERR:SYNTAX at the place where it was called on the homescreen.