2024-05-25 - In IL: Field Declarations
Last time we looked at the options for declaring fields in IL, today we are going to look at some examples.
This C# program has a variety of fields defined.
Let's start by looking at the accessibility attributes.
As expected we have the .field directive, the accessibility attribute, the type and the name of the field. The accessibility attributes line up the same as they did for the nested classes that we looked at previously.
Next we have some examples of the contract attributes.
Again this is as we expect. All the fields are private because we omitted the accessibility marker. The const field became static literal to indicate that it is stored with the class and it can only have the value specified. Note that the literal assigned to the field is wrapped in a type specifier. readonly became initonly with both meaning that the field can only be set in a constructor. The static field is also marked as static in IL.
Now let's look at some different type identifiers.
First we have the FileMode field, in IL this is marked valuetype to indicate it's a value type (it's an enum) and then we get the fully qualified name of the type [mscorlib]System.IO.FileMode. The [mscorlib] part indicates the assembly that contains the type. The FileInfo field is marked class to indicate that it's a reference type. The Complex field is also marked as valuetype because it's a struct and we can see it's from a different assembly ([System.Numerics]) than the others. Finally we have the built in types which just replace the C# name for the type with the IL name for the time.
To finish off, let's look at some array fields.
Arrays are indicated by the [] at the end of the type name the same way they are in C#.
Well this was all very straight forward. Next time we will look at the instructions used to work with fields
2024-03-16 - DataTypes: Negative Numbers
In the last two posts we've been looking at positive binary numbers but what about negative binary numbers? How do we represent those? The simple answer is that you put a negative sign in front of the number, so –101 would be –5, but that just changes the question to how do we record a negative sign with bits?
Well, we have a few options.
Sign and magnitude
The simplest way is to use one of the bits to indicate the sign. This is typically the most significant bit. So if you were using an 8-bit byte to store a number, bit 7 would encode the sign and bits 0-6 would encode the value. This means you can encode the values –127 to +127. The sign bit is usually 0 to indicate positive and 1 for negative but it's only really important that the machines using these numbers are consistent about the meaning.
The main problem with this approach is that it requires computers to analyze the bits before performing operations.
5 + –7?
We are adding a negative value so that can be converted to subtraction.
5 – 7
The right number is bigger than the left number so we know the value will be negative and the value will be the same as if the subtraction was done the other way around.
-(7 – 5) = –2 = 5 + – 7
5 + – 3?
We are still adding a negative value so that can be converted to subtraction.
5 – 3
This time the right number is smaller than the left so we know the value will be positive and we can just do the subtraction.
5 – 3 = 2
Another oddity with sign and magnitude is that you have both –0 and +0 as we can have a zero magnitude with either sign.
This isn't terribly complicated and, as we will see later, this is how standard floating-point numbers are encoded. It would be nice to speed up the process if we can, especially when computers are going to be doing these kinds of calculations billions of times a second.
Ones' complement
Another option is Ones' complement which defines negative numbers as being the binary complement of the positive number with the same value. Binary complement means to flip all of the bits, 0 –> 1 and 1 –> 0. So for –56 we take 0011 1000 (56 in binary) and flip all the bits to get 1100 0111. The most significant bit still acts as a sign bit as it will only be set for negative numbers but now it's also a part of the value. The range of values is still –127 to +127 and we still have two zeros (0000 0000 and 1111 1111) but we have to do less special work to handle negative numbers in calculations. We add and subtract numbers as normal but if we get a carry or a borrow left over then we have to apply that back to the result.
For example if we were using 4-bit numbers we could do 5 + -7 which would be 0101 + 1000 (The complement of 0111 which is 7).
We know the result is negative because the most significant bit is set and if we take the complement we get 0010 which is 2. So 5 + –7 = –2 as we expect.
What if we try 5 + –3? That would be 0101 + 1100.
Our current result is 0001 which is 1. 5 + –3 = 1? That doesn't seem right. We have a carry left over though, so with ones' complement we need to add that back to the result.
Which gives us 0010 or 2. 5 + –3 = 2 makes a lot more sense.
So Ones' complement simplifies performing math with negative numbers at the cost of making negative numbers a little harder to decode. Can we do better?
Two's complement
The answer is yes. Two's complement defines negative numbers as being the complement of the positive number plus one. This is sort of like pre-including that extra addition step. The easiest way to determine the Two's complement of a value is to switch every value after the first 1. So for –56 we start with 0011 1000, keep all of the bits up to the one in the fourth spot the same and then flip all the bits after that to get 1100 1000.
You can also think of this as simply making the most significant bit negative. So you can determine the decimal equivalent of 1100 1000 by calculating –27 + 26 + 23 = –128 + 64 + 8 = –56. Like Ones' complement we don't have to handle the sign separately but now we also don't need to perform a second calculation.
For 5 + –7 we do 0101 + 1001
Again the most significant bit is 1 indicating a negative number. If we take the two's complement of 1110 we get 0010 which is 2, so the result of 5 + –7 is –2.
And for 5 + –3 we do 0101 + 1101
We ignore the carry out in this case and get 0010 which is the correct result of 2.
We can also think of negative numbers in two's complement as being the positive value subtracted from 0. To determine –9 we can calculate 0 – 9 or 0000 – 1001.
Which gives us our expected result of 0111. To do this calculation we had to borrow from some kind of nether space but that's okay because we got the result that we wanted.
With an 8-bit Two's complement number the range of values – 128 – 127. So we have an extra value now. Another benefit of Two's complement is we only have one zero because the two's complement of 0000 0000 is 0000 0000. So that's nice.
Two's complement is by far the most common way to represent negative numbers because we don't need to do any extra steps to get the correct result.
Next time we will start to look at fractional numbers
2024-01-14 - Adventures in Text Interfaces
For a while now I've been curious about how full screen MS-DOS applications were made. The kind of programs that have menus, scroll bars and pop-up prompts. Stuff like Edit or the various DOS IDEs. They seemed pretty common so I assumed that there would be a lot written about them, I was wrong and that just made me more curious.
My first problem was coming up with the right terms to search for. Searching for "Text Interface" leads to a bunch of pages taking about it in an abstract sense but nothing specific. Adding "DOS" helps a little but but you still end up with a lot of general discussion. Adding "Programming" would just flood the results with discussion of DOS programming in general.
Eventually I found a page talking about programming with DOS conio and this seemed promising but it was also very confusing. For example, the page talked about the conio library but none of the functions mentioned on the page appeared in any examples of the conio library I could find. This article was talking about FreeDOS, so I assumed this was a modern implementation that did things differently.
Later I figured out that the confusion was coming from differences between different compilers. The Microsoft compiler implemented a lot of its drawing functions in graph.h, you can see it being included in all of the examples on that page. Borland had those kinds of functions in conio.h but with different names. So conio + function name didn't give any results because the conio with those functions didn't use those names and the functions with those names weren't in conio. I imagine the writer of that article used Borland back in the day which is why they associated that kind of programming with conio. Microsoft used conio for functions more related to command line programming (Where text is printed to the screen one line at a time).
This did lead me to the header files and functions that I was interested in but I still couldn't find any good examples. The compiler documentation I had did give examples of how to use the functions but nothing about how to combine them together.
Unrelated to my text mode interface searches, I've also been looking for old software and documentation on eBay. One of my saved searches was for "Programmer's guide" in an attempt to find books talking about how to program for various systems. From this search I found a book titled "C Programmer's guide to Graphics" by James W. McCord. This book is geared towards programming in graphics modes and not text mode but it did get me thinking. The book is titled "C Programmer's guide" and not "DOS programmer's guide", maybe that's my problem.
So I did some searches for "C programming text interfaces" and eventually found "User Interfaces in C" by Mark Goodwin. This book was exactly what I wanted and gave a bunch of examples of how to write text mode user interfaces for MS-DOS applications. Of course the words "text-mode" and "MS-DOS" don't appear in the title of the book.
I'm not sure why the book was titled this way. Putting "C" in the name to indicate what language it was using makes sense but why not mention what operating system it was for? It was published by Microsoft Press, did they assume that only MS-DOS users would be looking at their books? Was it just that MS-DOS was ubiquitous at this point and no one would have thought you were talking about something else?
It just goes to show that one of the problems with searching for things is that you don't know what to search for until you've found it.
At least I have some DOS text mode programming examples now.
2023-12-31 - 2023 Retrospective
I think this year overall has been an improvement over previous ones. I have gotten more done this year than in the last few years and I'm making progress on some things. Progress is important.
So starting with more personal stuff.
Cats
The year started off a little stressful with Robin having the days where she wouldn't eat. I tried to make changes and it would seem like it was getting better and then it would get worse again. In March there was a few days where she wouldn't eat her wet food at all (she was still eating her dry food). I took her to the vet for tests and they were a little concerned about her kidney number so I ended up switching her to urinary tract food.
In the fall I was also getting concerned about her pooping. I've started giving her some senior food (it has more fibre) in addition to the urinary tract food and I've also changed her litter. It seems like she may not like the pellets that I was using to try and cut down on the dust for Lupo. She may also like deeper litter and I was purposely keeping the pellets low because they degrade and I didn't want to throw away a bunch at a time.
Her main problem seems to have been Lupo. When she stopped eating I bought some new feliway diffusers and that seemed to help a lot. I also put a cardboard box between their bowls and started feeding her before letting him out of the bedroom. That seems to have done a lot to improve her mood. I've been trying to referee between them more but that's a stressful job and I'm not always where they are.
Over the summer I was doing clicker training with the two of them. I would try and get them to sit next to each other and then give them treats. This seemed to help but may have also been causing some digestion issues so I put it on hold while I sorted that out.
Lupo is doing well. I changed his food and it seems to be agreeing with him a little better. I also stopped giving him dry food which seemed to get stuck in this throat quite often. We seem to have gotten into a good routine with his cleanings. I think there's only been a single time when he seemed like he was having a major issue. That passed fairly quickly and was likely just a bit of something caught in his throat and he felt better after he managed to cough it up.
He does like to worry me though. He has a red spot in the upper part of his tracheotomy which sometimes swells up and that makes me concerned that his hole is changing shape. I've been trying to keep an eye on it more but it's difficult to predict when there will be a problem to know when I should keep a closer eye on him.
The biggest thing lately has been trying to listen to him more. To accept when he doesn't want a cleaning and to trust that he'll be okay.
Sickness
I had several more throat issues early in the year. I didn't take antibiotics for them and I still got better which means it's probably not a bacterial infection but I'm not sure what it is.
I tried seeing my doctor about them but he had no interest in helping me. I asked for a referral to an ENT but he said they were only surgeons and would laugh at him. I think he just didn't want to do any work.
I have been taking allergy pills whenever I start to have a sore throat and that seems to help prevent major issues. I have no idea if it's a good idea to take allergy pills for long periods of time but it seems to help.
I had less problems over the summer but things got worse in the fall. I had one episode where I actually had to take a sick day but other than that it's just been long periods of kind of feeling ill.
It might also be a stress/sleep issue. I started listening to the relaxation recording before bed and that seems to have helped me sleep better but I think my stress levels are still very high.
House
My house plans got side tracked by a leaky bathroom vent. It turned out that it wasn't sealed properly and that the ducting also wasn't installed the way it should have been. This turned out to be a very expensive repair but I am a lot more comfortable having Lupo in there now and there haven't been any more leaks.
I bought a reclining chair for reading in the basement and many more bookshelves.
Volunteering
In February I participated in a resume review ran by APEGA for students and that was a lot of fun. I also sat in on a presentation about a possible APEGA program for universities. In May I volunteered for a local clean-up day which was also a lot of fun. It mostly involved throwing things into garbage trucks.
In September I started volunteering at the Library every other week for Teen Tech Lab. The Library has a room with a bunch of stuff in it and they let teens come in and do whatever they want. My role is mostly to supervise and to help the teens if they are having a problem.
I'm not sure if this is what I am looking for but it feels good to get out of the house and to do something. For a long time I was worried I would never find a volunteer position I was interested in.
Videos
I've made two episodes of Mafia Story Comparison and a mini-episode this year. I really enjoy making these videos and there's a lot more I want to make videos about but I'm realizing that they require a lot of time. Not only in terms of actually making the videos but also in terms of learning how to make videos.
Collecting
I've been trying to cut back on my collecting this year as it can be very expensive but I still managed to get quite a few cool things. I've also found quite a few things that I thought would be impossible to find, so that's good.
Breadboard Computer Project
I managed to finish the computer this year and even added buttons which aren't mentioned in the videos. I got the ROMs that I needed and also got a zero-insertion-force (ZIF) socket to make them easier to insert and remove.
I added options to the example program in the video so that using the buttons I can increment or decrement the number displayed on the screen by 1 or 10 and reset the number to 0
I started documenting the 6502 instruction set but the documentation and the project are currently on hold as I work on other things.
PenguinCooker
This is an application that I've been wanting to write for a while to help me maintain my website. My main push for writing this application is that I want to document the programs that I have purchased and that includes having pictures of them but currently I don't have a good way of uploading pictures to my website.
The application reads information from the remote database to display the current state of the website. When making changes it writes to the remote database and uploads files to the FTP site as well as trying to update the local database. Local database changes may not be applied if the current state of the data doesn't match what's in the remote database.
I have implemented the ability to add and edit picture sets. I also updated the app and website to support nesting picture sets which will make organization easier.
Floppy Disk Archiving
Early in the year I started collecting the parts to build a Floppy Archiving setup. This includes two USB floppy controllers, three floppy drives (a 3.5" drive, a 360K 5.25" drive and a 1.2M 5.25" drive) and two enclosures (1 for the 3.5" drive and 1 for the 5.25" drives).
The first 360K drive had some issues reading disks and had to be replaced. It doesn't recalibrate itself after being reset which leads to some inconsistencies when the floppy controller tries to move the head. It also seemed like it had problem reading data from the higher tracks.
I also ran into issues converting between disk image floppy formats. The USB floppy controller generates SCP files. These files break up the disk into tracks and records the amount of time between flux transitions. This gives a really accurate copy of the disk but isn't as practical for actually reading.
HFE files convert the timing information into the binary information encoded on the disk (including the bits used for clock synchronization) and IMG files contain the raw binary data encoded on the disk.
The first problem I ran into is that the SCP file wants extra tracks in case anything interesting is written to them but the IMG files shouldn't contain these tracks as they shouldn't contain valid data. The program I was using to convert the floppy images to IMG files was including extra garbage at the end of the file from these extra tracks.
I ended up writing my own HfeToImg converter program which reads in an HFE file and generates an IMG file but only uses 40 or 80 tracks. This was mostly an exercise in understanding the MFM encoding scheme which is actually pretty interesting. The program also validates the checksum of sectors which has been very useful in confirming I got a good read of a disk as the other program would just save whatever.
The next problem I had is that the HFE file generates from the SCP file seemed to be missing data. Eventually I figured out that this is because the tracks aren't recorded consistently on those disks. The start point varies from track to track. This wouldn't be a problem for actual disks as the drive could just keep reading the disk and find the rest of the data but HFE files only contain a single rotation and so all of the data needs to be there.
I started writing an ScpToHfe converter but this proved to be much more complicated. The SCP file encodes the time between flux transitions. A flux transition occurs when the magnetic polarity of the particles on the disk reverses and always indicates a binary 1. The number of 0s between the 1s is determined by the amount of time between the flux transitions. The issue is that this time isn't consistent between disks as it depends on the drive that wrote the disk.
I currently have a rather crude implementation that sort of works. I have started to reverse engineer the converter that I was using to understand how it works but there's a lot of code there. I'm hoping that not all of it is involving in the actual decode logic but we shall see.
Stats
- Blog posts – 5
- Writing pages added - 13
- Videos made – 3
- Books read – 12 (2 Programming Textbooks)
- Programming textbook chapters completed – 17
- Programming project commits - 39