Lots and lots of updates. Check out the changelog!
Yeah. So after teaming up with Pushead/Hokuto Force, I’ve already managed to squeeze out 4 new version of the TRSE IDE, with heaps of compiler optimizations (pun intended), IDE usability improvements, help, tutorials, complete overhaul over the raster IRQ system etc.
During the next month, I’ll be focusing on finishing the tutorial game + start on another game + creating a bunch of more tutorials. Also, we hope to release a first (!) ever C64 intro made with TRSE, I guess that will mean something.
Back to work, but still found time for some updates.
Compiled a pre-pre-alpha version (win64 only) that can be downloaded from here, currently version 0.001. Lots of bugs, but nice to have a first version. Here are some updates:
RasLib bitmap graphics libraries. Draw lines in bitmap mode! Works for lines that are smaller than 75% of the screen, but still. Lines, man.
Some gfx speed utilities as a built-in function : (fast) clear bitmap screen etc
While writing these libraries (and swearing), I discovered that something as amiss. While I previously had optimized statements such as a:=a+1 -> inc a, I realized with horror that I had done no such thing for binary operations of the type “a:=a+b”. Binary operations regularly requires a temporary variable, especially in larger expressions (a:=(sin(b)*d + 5)*e), but most regular expressions actually seems to be of the type b:=b-c etc. Using temp variables here are horrendous.
However, as is common knowledge among young girls nowadays: “When developing a compiler, first make sure that it works, then optimize”. I’ve now implemented an optimized version for binary operations of the type a:=a\-b, which also includes arrays (a[i]:=a[i] +c) etc. For most of my code, this optimized away between 1-3% of the complete code, but more importantly, these operations are very common in inner loops.
The final thing is the mess with integers. I’ve added some more functionality, and try to fix bugs whenever they show up. Which is often. For instance, I realized I had not yet implemented support for adding numbers larger than 255 to integers etc, but this should be fixed by now.
Finally, in the next version I’ve decided to drop the compulsory hash # prefix to all integer literals, and instead require memory addresses to have something like an ampersand &$2000.
So I really love writing compilers, procedural graphics routines and stuff like that. However, writing GUI is more of a hassle. That’s why everything is now properly simplified with OOP.
This now implies that every type of drawing, from the level editor, multicolor images, sprites and character sets are now structured in such a way that the code is well-structured and just.. smooth.
Anyways, a few new features:
Multicolor only, but easy to fix. Also need to add an option to export only a select number of sprites.
Previously, character sets were basically just multicolor images. Kinda annoying when drawing individual chars, especially when considering repeating tiles. You can now display individual chars, 2×2 blocks or 2×2 repeat blocks.
Example of a 3×3 grid of repeating tiles. In addition, you can copy and paste characters (and sprites).
The level editor is greatly improved, now with better data input – including header titles (so you don’t have to remember what each row does). You can specify the data headers in the project file.
- Bugfixes in the project systems/recent projects.
- Settings with paths to emulator/dasm
- Improved compiler output
- Improved optimizer (both post-processing and internal optimizer)
- Better error handling
- Tutorial game about 50% complete. Will be pretty hard.
- Tutorial game intro & game over screen
- Fixed a SID bug error
During a cabin trip the next couple of days, I hope to fill in a couple of missing stuff:
- More general settings
- GUI Notifications / messaging
- Rewrite some internal built-in-function load/save asm variable structures.. currently a mess, because I didn’t know how to to it at first. (LoadVar a/LoadIndex xy)
- non-multicolor sprites and charsets
Well. Easter finally happened, and I ended up spending most of my time doing something boring. At least, partly. But quite important, nevertheless.
I implemented a full “document”-structure in the TRSE editor. This includes
- Having projects (with individual settings)
- Having multiple documents open
- Displaying labels of said documents
- Project and global settings
- Fixing annoying bugs in the editor GUI
- New level editor data format
- Optimizing image displaying routines (threads going haywire etc)
- Remembering open files, recent projects etc
On the compiler side, the following stuff was added
- Updating checks for errors from Dasm
- Rewriting new cycle routines
- The best part: optimizing conditionals. I realized that like, 80% of my conditionals were simple “if a>b then…” , so you really don’t need the full check with logical conditionals. In addition, I added a check on whether the main block had more than ~80 instructions (on average, 128 bytes), and if this was the case, just use regular bcc etc to jup to false conclusions. This basically decreased the code size of *all* tutorial with 15%, and increased both my speed & happiness by about 20%.
But in the end, I realized how much I hate writing GUI-stuff. Luckily, most of the required shenanigans are now implemented, and I just need to test for bugs (while actually developing the game)
SOO MANY FILES OPEN AT THE SAME TIME, IMAGES AND SOURCE
I’m constantly updating the tutorial game, and yay, it is getting *bigger*. However, after the recent optimizations, the code size was actually decreased by about 25%, while speed increased almost as much. Which is good. I guess.
I’m currently shifting focus from GUI and editor document updates to actually finishing the tutorial game, but as usual, I am hitting new bugs and stuff. Like, I realized that I don’t have enough memory to actually include an intro screen, which is about ~10kb. sucks, but what can you do. The levels currently occupy 16kb of memory, and I’m thinking about new ways to optimize the data storage. But that is for a later post. Now I need to fetch another beer.
As I’m continuously improving and growing the software base, I thought I’d add an update section and start posting… well… updates. Hate calling it a blog.
Yesterday I sat down for eight hours straight and focused on optimizations & cycles. Stuff like
- a:=a+#1 now translates to inc a (as opposed to lda a; clc; adc #1; sta a)
- a[c] := a[c] -#1 now translates to ldx c ; dec a,x instead of the whole tirade of loading the index, transfering to x (which is performed for more complex operations like a[c+sine[y]] := b+a[i];)
- Tons of smaller optimizations, (like using “lda index ; txa ; sta stuff,x ” -> ldx index ; sta stuff,x” or numbers etc
- zeropage optimizations
I discovered that the output asm sometimes had a substantial of overlay in terms of lda/ldx, like
ldx index sta blah,x ; do more stuff ldx index sta blah2,x ;more stuff ldx index ...
I added a post-optimizer that removes all excessive ldx / ldy / lda, and stops removing when one of the states have been altered (or a jmp, rts etc). In general, this removed about 3% of the total source.
In addition, I realized that when declaring temp variables (for use in more advanced expression), I actually declare them *on the fly* and perform a jump to the next code statement. Which is stupid. So all temp vars are now declared with other variables, and all excessive stupid jumps are removed. Later, I’ll reduce the size of temp vars used by reusing them in a eh sort of medieval garbage collector. I mean, compile-time.
In the end of the day, I managed to get a 4000-line assembler code down to about 3600 lines, about a 10% reduction in size – and increase in speed.
However, I still need to optimize the conditionals. They can be quite brutal where they should be simple.
In addition, I decided to finally implement cycle counters. I entered all the cycle information (like lda #2 has 2 cycles, lda i has 4, lda (zeropage),x has 5 etc), and started counting. The counter is displayed per block/statement / conditional, and is shown here in the right-hand side of this image :
Unfortunately, the cycle counter doesn’t take into account all post-processing optimizations mentioned above (the ldx/ldy removal), but internal ones are included. I found the cycle counter to be quite handy, and managed to optimize a bunch of routines in the tutorial game.
I also fixed a severe bug that finally resulted in correct line numbers & automatic error location. However, still doesn’t work when you use include files. must fix later.
During the next couple of days, I’ll shift my focus to making the editor more user friendly, with stuff like
- Multiple documents
- Replace function
- Code completion?
- Specialized character set editor (not just using a regular multicolor painting)
- Remember line number of files
- Remembering open files
- Thinking about type structures (bytes for now), but they need to be fast-fast-fast…