Assembler, part 4 2017

What am I doing?

I've once again resumed working on the interface rather than the actual core; I still don't even know if any of this truly works. Sheesh.

Not a whole lot to report from yesterday as I practically spent the day reading while doing the odd bit of UI tinkering. Big thanks to Rob for reminding me about SyntaxBox! Scintilla is pretty horrible overall and SB is done so much better, so I'm glad the editor is now more solid. Code folding was extremely easy to implement, unlike Scintilla where I just couldn't be bothered and worked on another part instead.

Today I started a new control for displaying parsed instructions. Think of it as a ListBox but with no user interaction, and the "current item" is always vertically centred and highlighted; currently adding column support to tabulate the view. Oh, issue: I can't get the background transparent no-matter what. I've done millions of transparent controls in the past, so this is confusing the hell out of me.

Next, I need to have a go at actually executing instructions. I've done very little bit-work in .NET so I'm not sure how that's going to go, especially as I don't even know the syntax for VB.Net; presumably it's going to be bat-shit insane compared to C#.

Nothing instead of just null still annoys me to this very day.


Assembler, part 5 2017

In the previous version, Assembler parsed down the entered code into Instructions which contained an enum for denoting the type of that instruction. For example, Move being set as the property would mean it was a Move instruction.

Now that property has been removed and all Instructions inherit from BaseMnemonic (and some other interface). So, the Move instruction is now its own Move class.

All mnemonics for a CPU are defined within a Mnemonics collection when a Machine is instantiated (along with registers and such within the CPU class); there's (currently) a method that allows the mapping of a textual mnemonic to its class counterpart during the parsing stage; this may later be changed to a Dictionary or something.

Some limited parsing is in for determining what the source and destination operands consist of. This is the most complex part as those operands can contain everything from a plain immediate value to relative addressing.

Because of this, each instruction will have to maintain metadata on exactly what's going on within that instruction; having to parse more than once to later on to determine what needs to happen is silly, so lots of metadata is required. As a bonus, we'll get a ton of helpful debugging info for "free" when we implement all that gubbins.

On the interface side of things (c'mon, like I can resist UI work) the syntax highlighting now colourises the datatype (or size as is the actual term) for mnemonics. Turned out this was achievable via making the datatypes an operator when it comes to highlighting as they don't need to be on word boundaries - thanks to Rob for the suggestion. Still more highlighting work required.

The Registers window now has a trace of what it parsed from the entered source code and displays the interpreted code. Changed the font to a mono-space one as the other just looked messy when registers' widths didn't line up. Sorry Segoe UI - not this time.

Editor and Registers


Assembler, part 6 2017

Okay, okay; can't put off doing the operand parsing any longer if I want this project to progress any further.

Just like the (incomplete) line-by-line parsing of the entered sourced, I'm going with Regular Expressions. Everything is going to be regular expressions; regular expressions all the way down.

As there's no specific reason why the source and destination operands should be treated differently and so a generic parsing method is used for determining what an operand consists of.

The Operand object has, among other things, a Type enum property that specifies the type (oh, my!) of operand. This Type dictates what occurs when the instruction is executed. Currently, the following types have been defined:


There will no-doubt be more as I add parsing for additional features when I get the existing ones working. Types will certainly become more granular, such as specifying whether an Address is relative or absolute. Any BaseMnemonic-inherited class should be given as much information as possible to perform their function; there's no reason why they should need to perform any of their own interrogation.

The next big step is to have the Add mnemonic adding an immediate value to a register, but before that occurs, I'm going to need to sort out a couple of other things first.

Bit-work. All operations can work with either a byte, word, or long-word. Long-word is easy, but the other two will require bit manipulation of which I haven't really done much of in .NET.

Memory. Sure, the registers are currently just an integer(?) and so easy enough to work with, but what about addresses? There's not much point having address support if there's no memory to read/write with! I haven't really thought about this.

Initial thinking would be just to allocate an array that's a property of the BaseMachine class. I'm not going to add any CPU caches or anything of the sort as it won't make any performance difference as everything is so high level. Machine (memory, CPU, registers, etc) state will easily be serialisable and so can be "saved stated" for whatever reason.

Assembler, part 7

Haven't quite gone ahead with actually executing instructions as yet because I re-worked the way a "machine" is implemented.

I ended-up ripping out the hard coded properties and features and made everything generic. There's now a set of base classes that are used for implementing the CPU, Registers, Memory, and Mnemonics.

+ BaseMachine
  + Cpu
  + Memory

The first machine being implemented (as said from the very start) is the Motorola 68000. It's the first CPU I've used assembler with back in, ooh, 1995, maybe? It's also simpler and makes more sense than today's CPUs. Don't wanna go making things harder for myself.


The potential issue here is that registers are now loosely typed. I'm not sure how to go about implementing the usp and ssp registers. The pc (Program Counter) register can be added to the base class as all CPUs will require one. Not entirely sure what it will count, though.

When a new register is added to the Registers collection, you need to specify its base name, such as D (for a Data reg) or A (or an Address one). An index is automatically applied. The D, in this case, doesn't actually mean anything as far as the program is concerned. You can call the register(s) FloppyJobbies instead, if you wanted.

Anyway! If you wanted to add 8 Data registers, you'd do the following:

AddRegister("D", 8)

This will create 8 registers, all named D0 to D7. Basically, the index is applied directly after the base name.

Do CPUs only really have (general purpose) Data and Address registers? Could I replace the literal with an enum, instead?

Fetching a register? Like so:


With name being, say, "D6" to get the sixth Data register.

As I've (currently) implemented the Register collection as a list of type <Register>, I've added a Dictionary for caching purposes to save having to reiterate over the list each item a register is fetched. But, as registers are uniquely-named, I may just change the base collection to a Dictionary itself.


No changes have been made to mnemonics.


This currently just has a Map array of Integers. Other than that, I haven't done any further work on memory. Registers, above, is the current focus.


FileSieve 4.21 2017

As an excuse to use this new keyboard, I was going to rewrite a part of the FileSieve documentation but then I realised I didn't do a blog post for today. So here I am.

Today was spent working on FileSieve and getting command-line automation happening.

As part of my App Framework library, the Parameters class provided all the functionality I needed to get things moving fast. It was simply a case of reiterating over the Parameters.List collection and performing commands (aliases are also supported) based on what was encountered.

Due to this iterative nature, FileSieve can executes multiple commands from the command-line in sequence. So, for example: you can select a profile, start it, and then select another profile and start that, even making changes to it - and only it - beforehand.

The first added command was Profile, which is used like so:

-profile="My Profile"

This makes the GUI select the My Profile profile and make it active. All following commands are then executed on that profile.

Most of the commands emulate using the application's interface, such as RadioButton.PerformClick(). There's additional sanity-checking in there as it's accepting input from the user, but there really isn't much to it.

I did wonder about adding generic automation to the App Framework for all of my software, but it'll still take manual work to specify what's what. Probably isn't worth it, to be honest. Although I think Wake On LAN Ex will benefit from automation.

The 4.22 release will feature additional commands that aren't critical to using FileSieve from the command-line.

Oh, speaking of the command-line: the nomenclature has been changed from Command-Line to Automation. The reason being that I'd like to also add support for automating FileSieve usage via a text file. It'll basically be a top-to-bottom list of commands and parameters that FS iterates through executing one at a time.

To help with any debugging issues on the user's part, all automotive actions and their outcomes are logged under the Automation category in the Log window.

FileSieve 4.21 is available from FileSieve.com.


Comica Database Update 2017

Oh my, no update for a few days? It's the end times!

Nah, nah; I just didn't work on anything of note to write about. Already, a lot of the stuff I blog about I would never have previously done as they're not what I'd call "major", or even exciting. But I'm making myself talk about them anyway as it keeps content coming, so don't go thinking I'm thinking that I'm working on major works of art or anything - it's just more kahnent to babble about.

Alright, Comica. Not much to report on this other than I pushed a database update out for the first time in a while. Or, at least tried to.

I received a "Comic not working" notification (a feature I built into Comica that allows users to notify me of knackered comics) and thought, "Eh - why not?". I then ran a "deep validation" within the Comica Editor to weedle out any obviously broken comics while I was fixing up the reported comic.

Thirty minutes later (yes, it takes a while to manually go through the comics that the Editor says is broken; this is why I don't do full updates often, especially as I could be working on my commercial software instead), all fixed. Hit Upload and... nothing. The little console app that does the actual uploading appeared and then immediately disappeared. Uh-oh.

Loaded up the source and, oh, I should probably upgrade all of the projects to .Net 4.7. Did that and realised the configurations (x86, x64) were all over the place; there were even Itanium configs in there for some reason. Cleaned it all up.

Stuck a break point in the uploader source and immediately found the problem: the computer name it was expecting was different, so it bailed out.

When I created the Database Uploader console app, I put a quick 'n dirty check in there to ensure that it only runs on my PC. Turns out I hadn't changed the name of the PC when I installed Windows a couple of months back.

Fixed that and everything ran as before.

This got me thinking about doing a bit of work on the "next generation" of Comica (the editor is really nice!) - except it would have to be free, and then the thinking stopped right there. Ya can't live on free, son.


FileSieve 4.22 2017

Wasn't expecting that: made another release of FileSieve yesterday.

For no particular reason at all, a thought about the way FileSieve handles the Start automation command popped into my head while I was doing something completely unrelated.

I had a feeling of dread. I wasn't sure why, but it was there. Something was... wrong.

When my conscious mind caught up with the sub-conscious, it occurred to me: profile processing (which is what Start begins the process of but via the command-line) is threaded and consequently doesn't block the main thread. I didn't add any code to wait for that processing to exit; I just carry on with executing the remaining commands that were passed in via the command-line.

An enormous oversight as this means FileSieve is merrily executing commands while a profile is being processed, copying files and all sorts of stuff, while possibly nobbing things up left and right.

Loaded the code and then wondered how I was going to solve this. I forewent any semaphore or signalling as I wanted to get this update done and released ASAP. Instead, I made all automation commands asynchronous and then, in simple terms, busy-waited until it was complete.

I'm cheeky, me!

While I was in there, I decided to add support for allowing automation via an external file. FileSieve parses the file and then runs the encountered commands as though they were passed in via the command-line; lovely, lovely, code reuse.

As the file reading code is custom just for that task, I thought I'd allow line comments; any line that starts with a hash # character is ignored. Incidentally, all lines are trimmed of spaces.

Commands and their values can be spaced out however you want as, again, trimming is done before the fields are interpreted. As well as providing general flexibility in the syntax, it also avoids the commands/values looking all squashed together.

If the autofile is just feeding commands from the file into the command-line parser, does that mean... recursion? Yes, yes it does! If an Autofile command is encountered within an autofile, then that file is then parsed. Allowing this to continue unabated is obviously not a good idea as eventually a StackOverflowException is thrown - turns out at about 1,000 levels deep! No idea why I always thought stack overflows occurred at around 8 iterations. Maybe due to the contents of the stack / frame sizes.


VB Runtimes Pack, release 8 2017

Speaking of unexpected happenings, I got contacted a couple of days ago by someone asking me if the Visual Basic 6 Runtimes Pack was free for enterprise use (spoiler: it is).

The pack doesn't require me having to recompile anything using the Visual Basic 6 IDE, as I haven't had that thing installed in well over a decade, so I thought I'd repackage it in an updated installer.

Running the original VB Pack installer itself shows that it was littered with errors. Not errors in the files it was installing (well, maybe a couple - but more on that later), but in the instructions and license.

As with all of my software installers, there are three text documents the installer shows to the user.

There's the License that is shown at the very start which contains the licensing terms that must be agreed to before the installer will do its thing.

Second is the Before, which contains general information. In this case, it outlines what the pack is and what it'll install. Also included is the pack version and its release date, just like the other two docs.

Thirdly, and lastly, is the After. This is just a quick message letting the user know that everything is installed.

The problems are down to the site each document points to: they're wrong. As this pack was originally released way back in 2002, the URLs are pointing to my old site www.tnk-bootblock.co.uk as opposed to here.

Another problem is the release date. Each of the three documents mentioned above have entirely different dates! No idea how that happened.

Oh, the file errors that I alluded to above. There was a note in the Before text saying that any .dll registration errors that occur can safely be ignored. While setting other properties within the installer, I noticed there was a flag for ignoring any errors that are thrown during the regsvr process. Now that flag is enabled so the errors are no longer shown, if they indeed occur at all this time around.

As well as general quality control, I wanted to get this site properly advertised in there as there is a huge amount of downloads of that pack. It seems people and companies just tell their customers to download the installer from my site. I might as well get a little bit of advertisement from it as it's not exactly like I'm gaining anything.


FileSieve Documentation 2017

I seem to be on a major productivity roll lately. I realised why, too: this new Corsair K95 RGB Platinum keyboard (US version can be seen here). It might seem like I'm babbling on about mechanical keyboards like a zealot, but I had to plug in my previous rubber-domed Logitech G19 keyboard recently and holy crap. The holiest of holy craps.

Rubber-domed keyboards are genuinely 'orrible to type on!

Since I got this new keyboard (a week or two, now?), I just can't stop typing on it. I'm having to come up with excuses to work on something just so I can use it.

The upshot of this is that my productivity is going a bit insane. Even these posts you're reading are starting to be written days in advance - that's how much I'm writing now.

In fact, I've decided to add a whole new Automation section to the FileSieve documentation!

I don't even want to imagine how much output has been gimped while having to use that previous rubber-johnny keyboard. Ugh.


Documentation - is it worth it? 2017

It feels like I should be writing another post as it's been a few days. While that's technically true, there's been posts every day now but they were actually written earlier in the week and published once per day with the new timed publish update.

So I'll write a quick post about documentation. Specifically, the FileSieve documentation.

I haven't done any programming for the past couple of days and so thought I should at least do something, and that something was some FileSieve docs. I remembered a thing: a couple of days ago I looked at the Analytics for the FS documentation and it appears hardly anyone even looks at it.

So, really; am I just wasting my time with it? Honestly... yes, I think I am. I started reworking the single Automation page into an entire section before this realisation and now I'm starting to wonder if there's any point? Unlike a lot of the rest of the application, automation requires documentation.

Maybe I should just shove out the required info (and not bother polishing it all up) and be done with it and spend any other FileSieve time on the application itself.