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
2023-11-05 - In IL: Field Definitions
Fields are used to store information as part of a type.
.field <attributes…> <type> <Id> <initializer>
A field is declared using the .field directive. This is followed by a set of attributes which describe how the field behaves. The type indicates what kind of data the field contains, Id is the name of the field, and the initializer is used to set the value of the field
There are a variety of attributes that can be set.
Accessibility
The accessibility attributes are used to indicate where the field can be accessed.
Attribute | Description |
---|---|
private | Visible only within the containing class |
famandassem | Visible to containing class and derived classes within the same assembly |
assembly | Visible to the containing assembly |
family | Visibility to containing class and derived classes |
famorassem | Visibility to containing class and derived classes or to the containing assembly |
public | Visible everywhere |
Contract Attributes
The contract attributes are used to control how the field can be used
Attribute | Description |
---|---|
static | Indicates that the field is associated with the type. Not specifying static means that the field is specific to each instance |
initonly | Indicates that the field can only be modified in a constructor |
literal | (static only) indicates that the field can only have the value specified as part of its declaration |
Interoperation Attributes
The marshal (<NativeType>) attribute is used to specify how this field should be handled during marshalling
Special attributes
These attributes are used to indicate that the field should be treated in a special way
Attribute | Description |
---|---|
rtspecialname | The field has a special meaning to the runtime |
specialname | The field has a special meaning to something besides the runtime |
Type
We saw examples of types when we looked at variables. User defined value types start with valuetype and reference types start with class. This is followed by the fully qualified name of the type including namespaces and the source assembly. Built-in types use the simple name of the type and value or reference type is implied.
Initialization
initialization is specified using an equal sign followed by <type>(<value>) where type is one of the built-in types and value is the value to initialize the variable with.
Next time we will look at some examples.
2023-09-03 - DataTypes: Binary Arithmetic
Last time I said we would talk about negative numbers next but I realized I should probably explain binary arithmetic first. It's easier to show negative numbers working if you understand how binary math with positive numbers works. So that's what we are going to do today.
Binary arithmetic is actually easy. It mostly works the same as decimal arithmetic except we only have two digits instead of ten.
Lets start with a simple addition example, 8 + 3. In binary that's 1000 + 11. We setup the equation as we would normally and just go through the steps of adding each digit together in turn.
We start on the right hand side and get 0 + 1 = 1. Fairly basic math. This is the same for the second digit as well. Then we have a 0 which just drops down and the 1 does the same. This gives us 1011 which is 11 in decimal. 8 + 3 = 11 and 1000 + 11 = 1011.
Now let's look at something a bit more complicated, 15 + 25. In binary that would be 1111 + 11001.
Again we start on the right hand side. 1 + 1 = 10 (2) which means the result is 0 and we have a carry of 1. Carries work the same as they do in decimal math, they simply get added to the next digit. The next two digits are the same due to the carry being included in the addition. The fourth digit is 1 + 1 + 1 with the third 1 being the carry. 1 + 1 + 1 = 11 (3) so the result is 1 with a carry of 1. We then again have 1 + 1 = 10 and that gets added to the result which is 101000 or 40 in decimal.
As you can see the combination of digits is very limited. 0 + 0 = 0, 0 + 1 = 1, 1 + 0 = 1, 1 + 1 = 10. The most complicated calculation to do is 1 + 1 + 1 = 11 if both digits are 1 and we have a carry.
Now let's look at subtraction with 19 – 3.
We start with 1 – 1 = 0. This is the same for the second digit as well. Then we have 0 – 0 = 0, 0 – 0 = 0 and 1 – 0 = 1. This gives us 10000 or 16.
Now let's look at 20 – 3. That would be 10100 - 11
We again start with the right and do 0 – 1 which can't be done so we borrow from the next digit but the next digit is also 0 so it also needs to do a borrow. The third digit in the top number is a 1 so it can be used for borrow and becomes 0. Then working back the second digit becomes a 10 because of the borrow but we need to borrow from it so it becomes a 1 because 10 – 1 = 1. Now we have a 10 for the first digit and we can finally subtract the 1 so we do 10 – 1 = 1 again. For the next digit we have 1 – 1 = 0 and the rest of the digits just drop down to give us 10001 or 17.
Multiplication works like you would expect. Let's look at 26 x 3 which would be 11010 x 11.
With decimal multiplication you multiply the top number by each digit in the bottom number and then sum the results. Each intermediate result has one more 0 than the previous one. This is because each digit is 10 (or 2 for binary numbers) times bigger than the last. Binary multiplication works the same way. You start with the right most digit and multiply the top number by that. In this case the digit is a 1 so we just write down the top number as our first intermediate result. The second digit is also a 1 but we're in the 2's position now so we write down the top number with an extra 0 as our second intermediate result. This is effectively 26 + 26 x 2. Adding the two numbers we get 1001110 which is 78 or 26 x 3. Because binary only has two digits it's easy to come up with the intermediate values. They are either 0 because the digit is a 0 or the number shifted over a number of times because the digit is a 1. You can end up with a lot of additions to do if you have large numbers but the process is simple.
Division is similar. The number either fits and you put a 1 in the result or it doesn't and you put a 0. For example let's look at 30 (11110) divided by 8 (1000).
Like with decimal long division we consider more and more digits of the dividend until the divisor fits into it. Unlike decimal division we don't have to worry about knowing the multiples of the divisor. It either fits and the result gets a 1 or it doesn't and it gets a 0. After moving over three times we get 1111 which is bigger than 1000. So we subtract 1000 from 1111 to get 111 and then pull down the 0 from the dividend to get 1110. We then use this value and repeat the process. 1110 is greater than 1000 so we put another 1 in the result and take the difference. Pulling down another 0 we get 1100. Do it again and we get 1000. Once more and we get 0. Just as with decimal division the decimal point in the dividend and the quotient is the same. This gives us a result of 11.11. We'll look at fractional numbers later but for now just believe me when I tell you this is 3.75, the result of dividing 30 by 8.
Notice that we basically just shifted 11110 over 3 digits to get 11.11. This is because we divided by 8 which is a power of 2. This is the same as dividing a decimal number by powers of 10.
Note that computers don't actually do math step-by-step like this. They either use algorithms to speed up the process or have logic implemented in circuits which can determine the result electronically. For example the result of adding two digits (A and B) and a carry (C) is (A XOR B) XOR C. The result is 1 if either of the inputs are 1 unless the carry is also 1. The carry out logic is a bit more complicated but can still be implemented with simple logic gates.
It's also important to remember that computers mainly work on numbers with a fixed number of digits. This means that if a numbers get to big it ends up wrapping around because there's no more digits for it to grow into. Earlier we looked at 1111 + 11001 and got 101000 but if the this was a 5-bit computer the result would actually be 01000. That's because the largest value that can be stored in 5 bits is 31. The math is the same but the carry out from the final 1 + 1 is lost.
Computers actually use this as a trick to implement negative numbers as we will see next time when we look at how computers implement negative numbers. I promise will will actually do it this time.
2023-02-05 - Perspectives
A while ago I was walking down the street when I saw a hotel employee carrying the luggage of a fancy looking couple into a hotel. This started me thinking about how different some people's lives are. Having someone carrying their luggage probably feels normal for them but I would find it weird. "I can do that, you don't need to do that". Maybe they do find it weird. Maybe they only recently came into money or this is a special trip to commemorate their anniversary or they just find it weird even though it's how things have always been for them.
I've also been thinking about this in regards to pastimes. I look at people who play instruments or cook amazing meals and wish I could do that. There's no reason I can't except that I have my spare time ear marked for other things. Writing stuff like this, learning about computers, working on programming projects. Those other people aren't doing those things which is why they can cook and play music. I can't not program though just as they can't not cook or play instruments. Different people have different things that interest and excite them.
I enjoy my life. I think I had a pretty good childhood. I think I have good opinions about things. I think I'm productive in my free time. But I also think a lot of people would look at my life and go "huh?". I would probably do the same about their lives. The human experience is so varied that it's almost unnerving to think about. The number of people living entirely different lives. With different opinions, thoughts and priorities. There's people who can waste a billion dollars without blinking and there are people who would do anything for 5 cents.
It's difficult to understand people when you only see them through your own perspective. Through your own experiences. They don't share those experiences or perspectives so it's very unlikely that they will make sense in that context. To make sense of people you have to shift into their perspective, think about what they've experienced.
People are complicated.