2022-03-05 - An Incomplete History of Microprocessors
At the dawn of the computer age not only were they massive but their components were massive as well. Large collections of vacuum tubes or discrete transistors all wired together. A processor could fill a cabinet all by itself. The invention of integrated circuits allowed for all these components to be placed inside a single chip that could fit in your hand. Microprocessors are integrated circuits designed to process information and execute instructions. The shrinking of the processor lead in turn to the shrinking of the computer which allowed them to be used in homes and schools. Instead of needing a dedicated room computers could now fit on a desk. This list focuses on microprocessors used in consumer devices from the 70s and 80s.
1971 - Intel 4004
4-bit registers and data bus, 12-bit address bus (2048 bytes)
The 4004 was the first commercially produced microprocessor. Originally designed for calculators it soon became clear that it could be used to build a complete, if limited, computer
1974 – Intel 8080
8-bit registers and data bus, 16-bit address bus (64 kiB)
The 8008 was intel’s first 8-bit processor but it was the 8080 that really kicked off the microcomputer revolution. Computers like the Altair 8800 and the IMSAI 8080 were huge successes and lead to the standardization of the S-100 bus and CP/M as the first commercially available operating system.
1974 - Motorola 6800
8-bit registers and data bus, 16-bit address bus (64 kiB)
The 6800 found some use in early home computers like the Southwest Technical Products 6800 and the Altair 680 but it never caught on the way the 8080 did.
1975 - MOS Technology 6502
8-bit registers and data bus, 16-bit address bus (64 kiB)
Designed by former Motorola employees based on the 6800, the 6502 would go on to become one of the big players in the 8-bit micro generation. Used in computers like the Apple, the Apple II, the Commodore PET, the Atari 8-Bit family, and the BBC micro.
1976 - Texas Instruments TMS9900
16-bit registers, data bus and address bus (64 kiB)
Designed for use in TI own computer line-up the TMS9900 was one of the first 16-bit processors.
1976 - Zilog Z80
8-bit registers and data bus, 16-bit address bus (64 kiB)
Designed by former Intel employees and based in the 8080 the Z80 would become the other big microprocessor of the 8-bit era. It was used in computers like the TRS-80, Sinclair ZX80/ZX81/Spectrum and other business oriented computers. Being compatible with the 8080 it also ran CP/M.
1978 - Motorola 6809
16-bit registers, 8-bit data bus, 16-bit address bus (64 kiB)
The 6809 was similar to the 6800 but added some 16-bit features which gave it a step up over the other 8-bit processors of the time. It’s main use was in the TRS-80 Color Computer.
1979 – Intel 8088
16-bit registers, 8-bit data bus, 20-bit address bus (1 MiB)
The 8088 was used in the first-generation of IBM Personal Computers and is the grand-uncle of the modern x86 architectures which currently dominate the home computer market. It’s brother the 8086 had a full 16-bit data bus and was therefore faster but the 8088, with its smaller data bus, allowed for cheaper motherboards.
1979 - Motorola 68000
32-bit registers, 16-bit data bus, 24-bit address bus (16 MiB)
Although one of the first 32-bit processors the 68000 would become one of the main players in the 16-bit era of microcomputers with computers like the Apple Macintosh, Atari ST and Commodore Amiga.
1982 – MOS Technology 6510
8-bit registers and data bus, 16-bit address bus (64 kiB)
A modified version of the 6502 with I/O pins. The 6510 was used primarily in the extremely successful Commodore 64
1984 – Motorola 68020
32-bit registers, data bus and address bus (4 GiB)
A fully 32-bit version of the 68000 which found usage in revisions to the Apple Macintosh and Commodore Amiga lines.
1985 – Intel 80386
32-bit registers, data bus and address bus (4 GiB)
The first 32-bit implementation of the Intel x86 architecture that would become the mainstay of the PC world.
2022-01-23 - Programming Active Server Pages
Programming Active Server Pages was written by Scott Hillier and Daniel Mezick and published by Microsoft Press in 1997. This book discusses Active Server Pages (ASP), one of Microsoft’s early attempts at building a server-side website development platform. The idea is that you create .asp files with sections of VBScript or JavaScript code in them which is ran by the server and the resulting HTML page is then sent to the client. This is similar to ASP.net, JSP and PHP in both functionality and look. The main benefit of ASP like the other similar technologies is that you can have dynamic pages, pages where the content changes based on some condition, without needing to run code on the client machine. This has security advantages as the client has less of a chance to interfere with the operation and also means you aren’t reliant on the client supporting the technology you want to use. This book does some things I like and some things I don’t like so overall my opinion is very middling.
Starting with things I like. I like examples and this book has a lot of them. The practical examples are identified by numbered steps which helps to separate them from informational examples. They also go into quite a bit of detail which makes them easy to follow. The final few chapters of the book are entirely devoted to examples which is nice as it gives you an in-depth look at the things being talked about in the book.
As for things I don’t like, I don’t like books that aren’t clear what they are about. For a book about ASP this book spends a lot of time talking about non-ASP things like dynamic HTML and client side scripting. It’s a bit telling when you can make it to chapter 5 before the main topic of the book starts to get discussed. I don’t mind books that gives additional information but I feel like the the main topic should be the focus.
I also think the book should have focused more on the syntax of VBScript and JavaScript up-front. There’s an appendix dedicated to that topic but I think it would have been better if it was a part of the introduction. That might just be my preference for beginner books where the topic is explained from the ground-up and there isn’t a lot of assumed knowledge.
One final criticism is the reliance on pre-release technology. There’s a decent amount of ActiveX in the book, which is fine, but the book seems to have been written before all the ActiveX controls were finalized. This means that in some cases the GUID used to reference the control or the parameters used by the control in examples don’t actually work. It’s not clear to the reader if they did something wrong or if the book is wrong. I get the desire to have the book out in time for the launch of the functionality but It’s probably best to wait to write about things until you know they won’t change, otherwise you are just setting your readers up for issues.
Overall I enjoyed the book and found the writing and examples interesting. I think the book could have been a lot better if it focused more exclusively on ASP, has more introductory content about the languages used and didn’t reference things that were incorrect by the time the book was published but it’s by no means terrible.
2021-12-05 - In IL: C# Classes and Structs
Last time we looked at class definitions in IL, now let’s see how some compiled C# examples look. This program has a variety of class and struct definitions.
If we compile this we get a lot of code but let’s just focus on the classes starting with the internal and public classes.
InternalClass is marked as private and PublicClass is marked as public these correspond to the Visibility options we saw last time. Now let’s look at the nested classes.
NestedPrivateClass is marked as nested private, NestedPrivateProtectedClass is marked as nested famandassem, NestedInternalClass is marked as nested assembly, NestedProtectedClass is marked as nested family, NestedProtectedInternalClass is marked as nested famorassemand NestedPublicClass is marked as nested public. These correspond to the Accessibility options. Note that on a nested class internal is compiled as nested assembly but on the non-nested class it’s private. Also note how private protected and protected internal get compiled down to famandassem and famorassem respectivly. C# is trying to limit its keyword usage which can lead to confusing situations where as IL is trying to be much more explicit and clear in what it’s doing. Trade-offs of the differing goals of the two languages. Now let’s look at the interface.
IInterface is also declared using the .class directive but it has the interface attribute applied to it to mark it as an interface. It’s also marked as abstract which means you can’t declare an instance of this class, which makes sense for an interface. We can also see that option if we look at AbstractClass.
Now let’s look at the SealedClass.
It's marked with the sealed attribute which means you can’t derive another class from it. So far these examples have mapped fairly easily from C# to IL but how does StaticClass map? There’s no static IL attribute. Well let’s see.
It combines several attributes to achieve the desired result. We have the abstract attribute to prevent instances of that type from being declared but it's also marked as sealed so you can't derive a class from it and declare an instance of that. So by combining these two attributes the C# compiler has created it's idea of static without that needing to be specifically specified in IL. Now let’s look at DerivedClass.
It's marked with extends CsClass.AbstractClass. This is how base classes are specified in IL. Note how all the other classes, except IInterface, are marked as extending [mscorlib]System.Object. This is how everything can be treated as a derivation of Object because they are. This is implicit when defining C# classes but explicit in the generated IL. Now let’s see how InterfaceClass works.
It's also marked as extending Object but it has an aditional implements CsClass.IInterface which is how IL specifies the interfaces a class implements. Again notice the shift from implicit to explicit. In C# you simply list the base class and interfaces separated by commas but in IL you say it extends these base classes and implements these interfaces. Back to things that don’t seem to have options in IL, how do structs work? Well let’s see.
PublicStruct is also declared using .class but instead of extending from Object we have extends [mscorlib]System.ValueType. System.ValueType is a special class in IL that tells the runtime to treat the class as a value type which means that instead of references being passes around the actual value is passed around. Also note that it’s marked as sequential instead of auto. This is because the default behaviour for structs is to have the fields laid out in memory the same way they are declared in the struct. But what about enums?
PublicEnum has extends [mscorlib]System.Enum with System.Enum being another special class. Note that System.Enum derives from System.ValueType which derives from System.Object so everything is still objects in the end.
So as you can see everything in IL is actually a class. Some classes just have more options applied than others. Now a quick note about namespaces, notice that there aren’t any namespace declarations. Whenever we declare a class or reference a class we use it’s fully qualified name. Namespaces are a C# concept for making it easier to specify these names but they don’t really exist at the IL level. IL is meant for computers and computers don’t mind a little extra typing.
Next time we’re going to look at Visual Basic .NET classes, structures and modules. I bet you can guess how those are going to look once compiled.
2021-10-31 - DataTypes: Logical Values
Last time we looked at bits, binary digits, which can be either a 0 or a 1. Now the question is what can we do with these bits? Well the simplest thing we can do is treat them as logical or boolean values (named after George Boole and the system of Boolean algebra he developed). These can be either true or false. Many languages have a bool or boolean type which is used to hold these kinds of values. There’s a simple mapping between logical values and bits as both have only two possible values. Typically true is represented with and 1 and false with a 0 but this is entirely arbitrary. Collections of bits can be used to store a collection of logical values called bit flags or a boolean array.
Logical values are the basis for allowing computers to store state and make decisions. We can use a logical value to keep track of whether or not the oven is on and to perform a certain set of operations, like cooking a turkey, if it is and a different set if it isn’t, like turning it on. If the oven being on was currently false the computer would turn it on and then set the value to true. Now if the computer did the oven check again it would see it was true and cook the turkey. The computer could also have a loop that repeatedly checks to see if the turkey is cooked and once that becomes true it would take the turkey out of the oven and turn it off. These decision making and looping mechanisms are what allow computers to be smart. Without them they would be limited to simply performing the same set of operations every time.
Logical values can also be combined using various logical operators to produce new logical values that can be used for more complex decision making.
Not
The inverse, complement or not operation changes one logical value to the other. This allows you to perform an operation if a value isn’t true. (Not Hot) would be false if Hot was true.
Input | Output |
---|---|
True | False |
False | True |
And
The and operation combines multiple inputs and is true only if all the inputs are true. This allows you perform a specific operation only if a variety of conditions are all true. (Hot and Humid) would be true only if Hot and Humid were both true.
Input 1 | Input 2 | Output |
---|---|---|
False | False | False |
False | True | False |
True | False | False |
True | True | True |
Or
The or operation combines multiple inputs and is true if any of the inputs are true. This allows an operation to be performed if at least one of the conditions is true. (Hot or Humid) would be true if either Hot or Humid was true.
Input 1 | Input 2 | Output |
---|---|---|
False | False | False |
False | True | True |
True | False | True |
True | True | True |
Xor
The exclusive-or operation is similar to or but is false if multiple inputs are also true. This allows an operation to be performed if only a single condition is true. (Hot xor Humid) would be true if Hot was true or if Humid was true but not if both were true.
Input 1 | Input 2 | Output |
---|---|---|
False | False | False |
False | True | True |
True | False | True |
True | True | False |
Logical values are useful for storing simple state information but to really do stuff with computers we need the ability to store more complex information. Next time we’re going to look at integer values.