0 Members and 12 Guests are viewing this topic.
Nevertheless, it's always better (for the speed and for the program's size) to have the exact function needed. See spoiler.
By the way, Robbox seems to be a good game I'll try it.
But what you say here it completely true for pure Axe programmers.
Erm, it is not finished yet so you'll probably be disappointed
Also, sorry for forgetting my duty.Welcome to Omnimaga Zemmargorp.You can introduce yourself here if you didn't already
Hi ! I've been using Axe for one year now (since version 1.0.0), and I love it !It's way much faster than TI-Basic, and it's even easier to use ! Thanks for making Axe Parser !I have some little ideas to improve it... Here's my contribution !
First of all, Axe Parser should check if there's any backup kept in RAM and either 1] show it in the "Compile" list or 2] ask to archive it. Because one day, just after compiling, it asked me for "Garbage Collect" like it does sometimes, and I answered "no" by mistake. I then thought my source was lost, because the source program was removed and its backup wasn't shown in the compile list (as it wasn't archived). I spent one hour to write the full source code again from memory, beause I didn't know the backup was kept in RAM !
I have an idea to improve the drawing functions... I think that games made with Axe Parser are sometimes slow, especially when they use grayscale graphics on a TI-83+, without the "Full" mode. So why not adding new drawing functions like "Pt-On(", "Pt-Off(", etc. but wich draws sprites only on full bytes of the buffer, each 8 pixels, for 0<=X<=11 ? These functions could be accessed by adding a letter to the other drawing functions' name, "C" for example (stands for "column" and "clipped"), and could be named "CPt-On(", "CPt-Off(", "CPt-Change(", "CPt-Mask(", "CPt-Get("... Also, you could add "CHorizontal +/-" and "CVertical +/-" to move the screen by 8 pixels. I wrote all these drawing functions in assembly if you want (although they may not be fully optimised).
And to improve the datas, I think it could be great if we were able to make datas with binary values. To differentiate them with hexadecimal values, you could add the prefix "pi" to the data, like "pi[0101101010011001]->GDB1".
I imagined others features and functions, but they will be much more complicated to do...
And, talking about memory, why not also add a way to save the program's self changes from $9D95 to the compiled program ? It can be usefull for people developping games, instead of using an appvar only for the two bytes of the best score !
And I kept the best for the end : to implement a "Menu(" function, by using the OS's DIALOG bcalls ! I know you probably already thought of it, and it may be very complicated, but it's an important and so useful command ! I saw an amazing use of these bcalls in Brandonw's calcstuff, in the compressed folder "ddemo.zip", described in "dialogNotes.txt"... But it would be great to have at least the equivalent of the TI-Basic "Menu(" command.
If you use a smart shell that supports writeback, which is I guess the case for most people playing ASM games, you don't need to worry about making your program do that writeback itself A lot of Axe programs use writeback for saving, they don't all use appvars.
I think the problem is not that it is complicated, but more that it is a good learning experience for beginners to make their own menus, and not a good experience for non beginners to have an ugly menu in their program when they can have an awesome wheel such as that in TinyCraft But it's true that for debugging purposes at least, having a "fast" menu command would be great
First, you should add a command (and maybe associate it with the "Prompt" token) which inputs a number, because it's useful and a lot of people need this ! Probably use the "input" command, and then parse the returned string to convert it into a 2-byte number. You can make it able to convert the number into a float. For example, the command's syntax could be "Prompt A" to get a 2-byte number, and "Prompt float{A}" to get a float number located at the address pointed by A.
Talking about float numbers, here's another idea : it could be great to add the support in Axe of float numbers, by using the OS's bcalls. The tokens could be Axe's regular math tokens, with a dot just after, and the values would be located at the addresses pointed by the variables. For example, "A*.B->.C" would be compiled liked "Copy(A, OP1, 9):Copy(B, OP2, 9):bcall(FPMult):Copy(OP1, C, 9)". But maybe use the bcalls Mov9ToOP1/OP2 instead of Copy(VAR, OP1/OP2, 9).I've discovered there's an Axiom that allows this kind of manipulation with the OS's float variables, but it would be better to have it the way I described it, without having to use the OS's variables. Because it leads to creating the variables if they do not exists, looking in the VAT for the variable's address, and lose time. It's better if we use adresses of free memory for temporary calculations (in safe RAM areas, for example) and it's even better because it doesn't modify the OS's variables, if the calculator's owners stored important data inside them. It makes me thinking that it would be great to have a way to allocate/deallocate memory to a program, like "GetCalc(" does, but without having to specify a variable name, only the size needed.
And I forgot to talk about another feature I thought about. In some cases, it could be useful to have Axe's variables located in a specified data, to save/load default values easily with the "Copy(" command. I think the syntax "[X Y S ]r->GDB0" is great. And it could allow the programmer to add customs variables, with two-letters name : if he writes "[XpYpXeYe]r->GDB0", he could then use the additional variables Xp, Yp, Xe, and Ye. (It's not that 27 variables are not enough, it's rather that I prefer to use variables with a name that evokes me something, and sometimes I need several variables to memorize X and Y coordinates !)
Unless you know how to remedy my woes with input, in which case I'd love to include some more powerful default input commands that are mildly robust and programmer- and user-friendly.
I absolutely agree that Axe could use floating point support. But if I'm going to add it, I'm going to do it right. That means growing out of the everything-is-a-16-bit-integer system and providing actual types. So for now, ugly Axioms will have to suffice. But if and when Axe 2.0 comes out, this will be included.
If a program is in RAM when it is executed, it will simply be moved to $9D95, executed, and then moved back.So no matter how you execute a program, writeback should occur. In fact, the only problem should sometimes be preventing writeback rather than providing it.
I'd love for this to exist as well. I just have absolutely no clue how the OS dialog/menu system works, so have been unable to try to add it myself. If you think you know enough about it to be able to contribute this feature, that would be awesome.
Custom named variables were one of the biggest additions in Axe 1.0.0, and have as such been around for quite a while. Just as you use the °VAR syntax to retrieve the address of a variable, you use the addr→°VAR syntax to "store" a constant address of a variable so that VAR is then a variable that exists at the constant address addr.
You should look into more sources then. I didn't do a single program that doesn't use them.
Also for your input request, there is something like that already that has been done by nikitouzz :http://www.omnimaga.org/the-axe-parser-project/input-routine-done-!/
In fact, it raises a big question : should Axe become closer to TI-Basic with floating point maths, or should it stay closer to assembly and 16/8 bits maths ? Both cases are interesting, it depends what kind of program people make. But for beginners, being forced to use 16-bit is a good thing, because otherwise they would keep using floating point maths where they could use 16-bits maths, it wouldn't be optimized, and Axe would become a sort of TI-Basic II.
No, without any shell, it's not the case ! Even if the program is stored in RAM ! Personnally, I use Noshell on my TI-83+ (OS 1.19), and I tried a little program "{GDB0}++:Disp {GDB0}>Dec,i", and the output is always the same ! But maybe, yeah, as a lot of people are using shells with the write-back option enabled, they face the opposite problem (which is easier to solve, by the way).
Integer types would exist in tandem with floating point types, and you would pick what type different variables/values are. It would be very similar to a language like C.
Noshell has an option to toggle writeback, so it should support it. Also, I'd highly recommend replacing Noshell with zStart. It does everything Noshell does, plus so much more. Notable features for Axe developers are the ability to edit programs without unarchiving them, so you never have to worry about losing your source in a RAM clear, lots of helpful editor hooks like jumping to labels by name, and shortcuts to compile your program without even leaving editor. Also, zStart runs automatically after RAM clears, so all of its hooks and behaviors reinstate themselves without needing to run it every time.
Anyways, back to the topic at hand. Generally, as long as you run the program through any sort of shell/archived program running utility, writeback will be supported. So if you want to make sure writeback occurs, just compile your program with the MirageOS or DoorsCS header (I recommend the former, it's more widely accepted) to prevent it from being run by the OS.
bcall(_PushRealO1)
bcall(_PopRealO1)bcall(_ChkFindSym)JR C, SaveError ;Not found !XOR ACP BJR NZ, SaveError ;Archived !LD HL, DELD C, (HL)INC HLLD B, (HL)LD HL, $9D95LDIR:SaveErrorRET
I'm quite satisfied with Noshell. I've already heard of zStart, but I think it uses more than a single flash page ! And my sources program are always unarchived (with some backups on my computer), in case of RAM cleared (this occurs quite often).
It's a shame to prevent the program from being run by the OS just if you want to make sure writeback occurs ! Instead of preventing the user to execute the program if he hasn't got any shell, it's better to add a writeback routine inside the program ! I wrote a short code, which works when the program is shelled by the OS :Spoiler For Code: At the beginning of the program :Code: [Select]bcall(_PushRealO1)And at its end :Code: [Select]bcall(_PopRealO1)bcall(_ChkFindSym)JR C, SaveError ;Not found !XOR ACP BJR NZ, SaveError ;Archived !LD HL, DELD C, (HL)INC HLLD B, (HL)LD HL, $9D95LDIR:SaveErrorRET
zStart is also only one page.
However, the potential problem I see is that, when run by a shell, it may not be the case that OP1 contains the name of the program being executed. Best case scenario, it doesn't contain the name of a variable, and no writeback occurs. Worst case scenario, it contains the name of another variable, perhaps Ans or some shell appvar, and then the writeback clobbers RAM. Maybe I (or you) can round up all the main shells (MirageOS, DoorsCS, CrunchyOS, Noshell, CalcUtil, and zStart) and test this. If OP1 turns out not to be reliable, it would be worth checking progCurrent, progToEdit, and nameBuff.EDIT: Alternatively, it may be possible to detect if the OS or a shell launched the program.
Maybe I (or you) can round up all the main shells (MirageOS, DoorsCS, CrunchyOS, Noshell, CalcUtil, and zStart) and test this.
Regarding the OS's DIALOG bcalls, I've achieved to find a way to know which item was chosen by the user, in menus like TI-Basic provides. I just need to improve a little the code source... I'll publish it somewhere, but not now.