Author Topic: LangZ80  (Read 3705 times)

0 Members and 1 Guest are viewing this topic.

Offline Xeda112358

  • they/them
  • Moderator
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 4704
  • Rating: +719/-6
  • Calc-u-lator, do doo doo do do do.
    • View Profile
LangZ80
« on: January 16, 2014, 11:40:27 pm »
I started posting about LangZ80 in the FileSyst thread. Although I don't consider it a project-- it is more of a "proof of concept" program-- I have been having updates and instead of derailing the FileSyst thread, I brought it here.

Basically, I want to get FileSyst to a point where it can use variables and functions and basically work as a higher-level programming language and not just an exposed filesystem. I decided to experiment by creating a parser (yet again).

It is really broken and in a messy state, especially with the variable storage. There are lots of bugs there, as well as a few other bugs (integer that are multiples of 256 don't work properly, and I believe I left a few bugs in the float multiply routine). However, when I am not introducing bugs and things are working as they should, here is what it has:
  • Commands are typed out, like "UPDATELCD()"
  • Integers are arbitrary precision, from 0 to 2040 bits, in multiples of 8. These are unsigned.
  • Strings are supported. Start them with either " or ' and end them with the same token. This allows the use of quotes in strings.
  • Floats are supported. They default to at least 128 bits of precision (38 decimal digits) and at least 32-bits of precision after the decimal point. Floats can be arbitrary sizes, though, also up to a total of 2040 bits.
  • I have wrote the float_times_float and int_times_int routines, but not int_times_float and others.
  • It has an XORSPRITE() routine that was just for testing. It totally fakes the sprite rendering by not actually reading a sprite var and just assuming 8x8 sprites. Later this will change.
  • It has an UPDATELCD() command
  • It has a WAIT() command to wait for a key press
  • It has a few stacks to hold intermediate data. This part of the app is complete, to my knowledge. It pushes, pops, converts, updates pointers, all that good stuff.
  • When exiting, it returns "Ans" in the OS ans variable as a string (or it returns one of the various errors)
  • As such, it has an int?str routine, str?str, and most recently about an hour ago, a float?str routine.
  • It parses from prgmTEST
  • Storing and reading variables is almost supported. It is still broken and causes crashes, though.

It is really kind of garbage at the moment, but feel free to download it to test out in WabbitEmu. It is not stable and it will likely end up crashing a few times.

If at any point it seems like the program has frozen, it might instead be in the WAIT() loop or in another loop I made. To get out, try the following first:
  • Press any key that isn't [ON]
  • Press [ON]
If you have to press [ON] to exit, it was in a loop where I haven't added in the needed code yet, so I used that loop as a filler.


(also, it's 3344 bytes of code out of 16384)

Offline aeTIos

  • Nonbinary computing specialist
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 3915
  • Rating: +184/-32
    • View Profile
    • wank.party
Re: LangZ80
« Reply #1 on: January 17, 2014, 05:02:23 am »
So what does this do exactly? I'm sort of confuzzled.
I'm not a nerd but I pretend:

Offline Sorunome

  • Fox Fox Fox Fox Fox Fox Fox!
  • Support Staff
  • LV13 Extreme Addict (Next: 9001)
  • *************
  • Posts: 7920
  • Rating: +374/-13
  • Derpy Hooves
    • View Profile
    • My website! (You might lose the game)
Re: LangZ80
« Reply #2 on: January 17, 2014, 08:15:51 am »
So it is yet another programming language?

THE GAME
Also, check out my website
If OmnomIRC is screwed up, blame me!
Click here to give me an internet!

Offline Xeda112358

  • they/them
  • Moderator
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 4704
  • Rating: +719/-6
  • Calc-u-lator, do doo doo do do do.
    • View Profile
Re: LangZ80
« Reply #3 on: January 17, 2014, 11:16:56 am »
So what does this do exactly? I'm sort of confuzzled.
Currently, it is reading code and parsing it. It can only read integers and floats, multiply, do the XORSPRITE(), UPDATELCD(), and WAIT() commands, and you can technically store to variables, but that is a bit broken. For floats, it works to 38 digits of precision at the least by default.
So it is yet another programming language?
Yup :P Hopefully I can eventually provide a viable alternative to BASIC.

Offline Sorunome

  • Fox Fox Fox Fox Fox Fox Fox!
  • Support Staff
  • LV13 Extreme Addict (Next: 9001)
  • *************
  • Posts: 7920
  • Rating: +374/-13
  • Derpy Hooves
    • View Profile
    • My website! (You might lose the game)
Re: LangZ80
« Reply #4 on: January 17, 2014, 11:53:08 am »
So it is yet another programming language?
Yup :P Hopefully I can eventually provide a viable alternative to BASIC.
Isn't that what grammer is for already?

THE GAME
Also, check out my website
If OmnomIRC is screwed up, blame me!
Click here to give me an internet!

Offline Xeda112358

  • they/them
  • Moderator
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 4704
  • Rating: +719/-6
  • Calc-u-lator, do doo doo do do do.
    • View Profile
Re: LangZ80
« Reply #5 on: January 17, 2014, 12:25:34 pm »
When I say "viable alternative" I mean to address the fact that TI-BASIC is still the best language for math. As well, it provides a useful range of variable types.

EDIT: Also, I just added in better (but not perfect) rounding.

Offline DJ Omnimaga

  • Clacualters are teh gr33t
  • CoT Emeritus
  • LV15 Omnimagician (Next: --)
  • *
  • Posts: 55943
  • Rating: +3154/-232
  • CodeWalrus founder & retired Omnimaga founder
    • View Profile
    • Dream of Omnimaga Music
Re: LangZ80
« Reply #6 on: January 18, 2014, 12:49:02 am »
Interesting. Hopefully this is handy for those who make a lot of math programs .

Offline calcdude84se

  • Needs Motivation
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2272
  • Rating: +78/-13
  • Wondering where their free time went...
    • View Profile
Re: LangZ80
« Reply #7 on: January 18, 2014, 09:06:03 pm »
Interesting. Hopefully this is handy for those who make a lot of math programs .
Or even for those of us who just like messing around mathematically on their calculators. I really like Cabamap, for instance, but it's main shortcoming was that it only did integers. High-precision floats (even if only 255 bytes :P) sound like a lot of fun.
Zeda: Just how annoyingly hard would it be to support even larger numbers? ;)
Edit: The other limiting thing about Cabamap, now that I think about it, was that it didn't really integrate with anything. Having a programming language with support for all this sounds really cool. :)
« Last Edit: January 18, 2014, 09:07:06 pm by calcdude84se »
"People think computers will keep them from making mistakes. They're wrong. With computers you make mistakes faster."
-Adam Osborne
Spoiler For "PartesOS links":
I'll put it online when it does something.

Offline Xeda112358

  • they/them
  • Moderator
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 4704
  • Rating: +719/-6
  • Calc-u-lator, do doo doo do do do.
    • View Profile
Re: LangZ80
« Reply #8 on: January 18, 2014, 09:34:37 pm »
It would only require me to change from using 1 byte for the size to 2 bytes. In fact, I made an app two (or three?) years ago that used that high of precision. However, it took over an hour to perform a large multiplication. I think that was mostly due to the method I was using to multiply. The algorithm I am currently using is much faster, but I use an even faster version in my floating point library for 80-bit floats.

I could probably add another type of int and float that is basically max precision :P

Offline calcdude84se

  • Needs Motivation
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2272
  • Rating: +78/-13
  • Wondering where their free time went...
    • View Profile
Re: LangZ80
« Reply #9 on: January 18, 2014, 10:33:39 pm »
It would only require me to change from using 1 byte for the size to 2 bytes.
My main worry was that that sort of thing can sometimes completely mess with register allocation and such. Good to hear that that sounds like it wouldn't be a problem.
Quote
I could probably add another type of int and float that is basically max precision :P
That would be cool indeed.
I already have a potential use for this (which is straightforward enough that doing it in ASM wouldn't be too awful, but a language that would make it more natural is of course a good thing), but I'd also need key input, bitmath, direct writing to the gbuf, and loops. So eventually. :) (Maybe I'll write it in ASM first if I have the time) Good graphical display of mathematical things is awesome.
"People think computers will keep them from making mistakes. They're wrong. With computers you make mistakes faster."
-Adam Osborne
Spoiler For "PartesOS links":
I'll put it online when it does something.

Offline Xeda112358

  • they/them
  • Moderator
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 4704
  • Rating: +719/-6
  • Calc-u-lator, do doo doo do do do.
    • View Profile
Re: LangZ80
« Reply #10 on: January 19, 2014, 11:18:01 am »
What do you mean by direct writing to the gbuf? Like pixel commands? Except for the loops, the rest of it could be added now. I finally got variables working, so basically what is left is adding new commands and support for various data types.

Offline calcdude84se

  • Needs Motivation
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2272
  • Rating: +78/-13
  • Wondering where their free time went...
    • View Profile
Re: LangZ80
« Reply #11 on: January 19, 2014, 01:07:34 pm »
Well, for what I'm thinking of, I mean being able to write 12 bytes of an int to memory corresponding to a row on the LCD.
Congrats on getting variables working properly; it sounded difficult. :)
"People think computers will keep them from making mistakes. They're wrong. With computers you make mistakes faster."
-Adam Osborne
Spoiler For "PartesOS links":
I'll put it online when it does something.

Offline Xeda112358

  • they/them
  • Moderator
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 4704
  • Rating: +719/-6
  • Calc-u-lator, do doo doo do do do.
    • View Profile
Re: LangZ80
« Reply #12 on: January 19, 2014, 10:08:49 pm »
Well I could definitely add some command with that functionality. I guess it would take arguments such as the variable name, an offset, the number of bytes to read, and the location to output to? It would be one of the lower level commands, but it would be doable.

Now, here is where I am running into trouble: I realised before I added the "+" and ADD() instruction that string concatenation could reasonably exceed the 511 bytes of scratch RAM. As well, this scratch RAM (which is in fact 514 bytes) was allocated for the arbitrary precision arithmetic. However, for the much higher precision stuff, I would need some other dynamic location. Because of this, I am thinking of allowing those types of intermediate calculation to take place after the user variables.

On top of that, if I really want to remove this project even further from the OS, I wanted to take advantage of all of the available RAM pages. I am currently using 16-bit offsets to locate variables, so I am thinking that the easiest solution to working with the >16-bit range is to designate a table for every <65536 bytes. Either that, or I need to switch to 24-bit addressing, which might be the best option (but more difficult) if I plan to work with the flash, too.

My temporary fix to the first trouble is that I added in a variable type "indirect." This just holds the actual variable's name, so when an indirect var is parsed, it then tries to locate the actual var (and if that was indirect, it keeps going until it finds the root variable). The second will just be a pain for later.

While I was thinking about these problems, I decided to work out one of  the features that I forgot about. The first day that I wrote the parser, I added code to allow reading parts of lists, arrays, and strings. Of these, I only have strings variables actually supported. This means I have a routine that can get the size in bytes of a string variable, as well as locate a given element, and I have a routine that can generate a string variable and convert it to a string-- strings were trivial. So on testing, STRING1[3] (grab byte #3, 0-indexed, from STRING1), it crashed, but I managed to actually restructure it and get it working.

The whole thing still has bugs and such, unfortunately, but it is attached in case you want to experiment a little. I have to figure out why it only parses one line, now :/ If you want to step through the debugger, you can set a breakpoint at $4105 which is currently where the call to the parser is done to interpret prgmTEST.

EDIT: One person downloaded this, but I found that I left in a "jr $" opcode for debugging the routine to overwrite an existing variable. I reuploaded a fixed version. I usually use "jr $ " (with a space after $) so that I can easily find it with a search function and remove it.

Offline Xeda112358

  • they/them
  • Moderator
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 4704
  • Rating: +719/-6
  • Calc-u-lator, do doo doo do do do.
    • View Profile
Re: LangZ80
« Reply #13 on: January 20, 2014, 10:50:36 am »
Speed has been a noticeable issue since the last time I talked to calcdude on IRC. It turns out that the fancy wrapper I made called AllocateRAM around the OS bcalls _InsertMem and _DelMem-- while fantastic-- turns out to be reallly slow. I expected it to be slow, but not nearly as slow as it actually was in practice. On top of that, the way I was handling things before used a bunch of push/pop instructions for the various stacks and these required at least one use of AllocateRAM each. That meant the following took over 2 million clock cycles (1/3 of a second at 6MHz): 3*3*3*3*3*3.

After seeing that, calcdude mentioned that my method sounded kind of redundant and for the most part it was. I had scratch ram that I was working with anyways, so just switching to using that saved about 700000 t-states. I can't remember what else I did, but I have somehow managed to reduce the time needed to about 680 000 t-states (I cut out at least half the push/pop instructions). This is still terribly slow since each push and pop takes over 60000 t-states, it seems, so I will probably use a completely custom InsertMem/DelMem routine. I will also likely reorganise the memory structure of the GDB var I am using. While the LangZ80 parser is active, GDB13 will be expanded to fill RAM:

The start will hold the variable LUT for the binary search (grows upward)
Followed by this will be the variable data, the second most volatile region (grows upward)
This will be followed by the AddrStack which is a stack of pointers that get updated with AllocateRAM (grows upward, least volatile)
At the end will be the AnsStack which grows downward.

This should mean that push/pop instructions to the AnsStack will be as simple as updating a pointer and using LDIR if a push is performed. This will completely eliminate the use of AllocateRAM in that context. When adding a new variable, I can just insert it between the last variable and the AddrStack. Since the AddrStack will usually be small (<100 bytes, though I haven't had it larger than 2, yet), I will only need to move a small number of bytes to insert a new variable.
The slowest operation will then be resizing a variable. For example, if there are 10000 bytes of variables that needs to be shifted to add or remove bytes from a variable, that will take over 200000 t-states.

Finally, another speed optimisation that I made-- which seems tiny compared to the one above-- is in my binary search routine. Before, it was taking over 7100 t-states to locate the correct function, but I have now reduced that to 3100. I have added in the GETKEY routine, and I will try to add in a WHILE() routine, too. This will use the AddrStack to keep track of where the function returns and such. This means I will need to write the routines for comparisons.