Friday, 23 September 2016

Reading my Reddit Comments (4001 CPU)

I've recently noticed spells when these pages come up with lots of hits from other sources, by far the most common is google, however, just now and then reddit becomes a source of my views, so I decided to take a look... I was happy, surprise and interested to see the threads... Lets take a look.


By far the most common of my posts to appear in reddit threads are tutorials, an interesting one, at least to me, is my 4001 CPU post.  Of course it is a miss-noma for me to call it the 4001 a CPU... The intel 4001 was a ROM chip, the 4004 was the CPU in that series; strangely no-one spotted that intentional change, and I had thought they would.


Click here for the original post on this blog.

The post is about re-creating an integer CPU in code, it was a forerunner to a series for instructing a class, the next posts, which were planned were to include floating point mathematics, however, the whole series was put on hiatus, and I never returned to the topic.

ninereeds314 on reddit calls me out on this, about my commenting that about 486SX code, where I said: 

"I know this because I once got told off for designing code with my 486SX2 processor - which could only add and subtract in hardware"

He says:

"No - even 8086 had integer multiply and divide instructions. They were slow enough that it was often worth avoiding them and using shift instructions and similar tricks if you could, and they could only work with the AX and DX registers (e.g. for multiply, AX x Source -> DX:AX) but they were there.
The 80386 32-bit versions of DIV, IDIV, MUL and IMUL were very similar, but working with EAX and EDX rather than just AX and DX where appropriate.
It was mostly the 8-bit chips that didn't have integer multiply and divide instructions. IIRC the Motorola 6809 was one of few 8-bit chips to actually have them, but came too late for the peak of 8-bit home computers - I think the best known machine it was used in was the Dragon 32.
Other than that, probably early RISC chips didn't have built-in multiply and divide instructions. One of the principles for RISC (at least years ago) was that every instruction should complete in one cycle, but multiply and divide needed a lot of transistors to do that - in practice they used microcoded algorithms (which was why they were slow)."
He is perfectly correct, my passing comment is slightly out of context, the 486SX could do integer multiplication and division as he says, it could not do floating point however, as it had a defective FPU which they disabled in the factory.  This was what the SX was, a crippled DX, which Intel remarketed as a cheaper chip, rather than throw away.
My article however is about 8-bit code, and I wasn't clear, the 4004 could NOT do direct multiplication of integers, it performed the multiplication by looping, as I had done in my code for the 486SX.  My solution for my code was quicker on the 486SX, which could do the integer add very quickly, but the multiplications were somewhat slower, over 100,000's of calls this did add up, so I avoided it; and in the article I'm only talking about an 8bit integer CPU.  I wasn't clear enough.

However, choralone, comments directly after and spots what I meant, so I know I'm not completely lost.

This discussion continues between ninereeds, choralone and nerd4code, as they discuss more deeply what I'm describing, and indeed I see ninereeds explain that the x87 co-processors, were slower; here he's wrong, once the data was delivered across the FSB to the co-processor they were extremely fast, unfortunately the gated way in which data was shuffled to the cache on the co-processors meant that they were slower, they also only generally ran at 12Mhz, so processing on them compared to a 286 itself was fast, shuffling data to and from them, was quite slow.  As it held the whole bus, with interrupts disabled.

The 387 co-processor was quicker, but could not use a 32bit bus, hence the 486 was designed to have the co-processor (redubbed an FPU) built in, but Intel had fabrication issues, and the photo-lithography techniques of the day left a lot of chips with perfectly functional integer cores, whilst the FPU's were defective... The answer, they severed the link to the FPU, relabelled it the SX and you had an emulating software library call, which vastly slowed the 486SX series down.

About this thread of discussion, I only wished they'd have had it on my actual blog... We like-minded people could have made firm friends!

On the same thread, we spin forward and the user "immibis" picks out my comment about where historically CPU's pick up their first instruction upon power on... he says he finds it hard to believe that they would pick a location in memory.

Well, they did, if a CPU picked 0x00 as it's start point, often it was not clear whether the CPU was reset, just powered, whether all the chips were ready, or the sync signal or whatever technology they had was ready, so it was common practice to have a all lines held low, and then raise on high along with the clock to indicate the start point of the CPU when it was literally first powered on, this high-line in early implementations (and indeed solid state machines before their being silicon) meant they didn't address zero, they in fact addresses a higher part of memory.... 0x800 was a common location for some machines I programmes for early on in my career.

Sometimes, as "jslepicka" points out, it was because the start of the address space was ROM, so the first instruction for execution was in ROM at memory address 2048, the preceding 2047 bytes had library calls, system calls and interrupt handling code in them.  And they were (sometimes) in physically different ROM chips, which could and would be swapped on development machines or embedded devices, so you could upgrade the system calls, patches to calls in these early 2047 bytes often turned into JUMP instructions out to new patches in higher areas of memory beyond the start, and then a series of NO-OP instructions to stop them being used.

However, some early machines had all the RAM at the start, and the ROM on a different address space, so you had to pull a line high to get to ROM over RAM (or vice versa), so you had two different memory spaces to address.  In those systems, you often had the problem that they were dodgy, memory was pretty daggy stuff, and chip failure rate high.

So, common practice, was to skip the first memory RAM chip at boot up, and use the second or third chips, according to the physical wiring diagram.  So the first chip, which would for a matter of pico seconds (or nano seconds, or however long the electricity took to start to flow) have an "over current" or jolt, was NOT being used.  As they genuinely tended to go bad more often, so much so it became routine for vendors, like Digital, to provide a book on how to actually make (with a soldering iron and logic chips!) your own replacement, or expansion memory!



There is also direct evidence of this in the books, of the skipping RAM and ROM, concepts... where you can still see references to the PWRUP functions, which established the power state (or power failure state) of AST (Async-System Trap) entry point addresses.  These AST entry point addresses were never ever 0x00, because... well that's just all the lines pulled low, i.e. no-power, and not indicative of the power being on, or off or in any state really.

Of course, I reference things from way before the PC era, when computers still came with manuals on the actual logic gates within...


Thanks to AlexeyBrin for posting my blog to Reddit, and thanks to all those whom commented, I had fun reading this one.

Thursday, 22 September 2016

Great British Bake Off... All Hands to the Pumps!

With the bake off heading over to Channel 4, it's been interesting to see one of the most talked about programmes in our office be re-discussed... It's also extremely interesting to get the inside track on some things, since I work with an Bake-Off contestant... Jordon Cox


So this morning, as we stood in the kitchen getting our coffee talking Networking issues, it was very interesting to see his reaction of non-surprise that Mary Berry would be staying with the BBC rather than going over to Channel 4.

We can all guess she was offered a large slice of the millions Channel 4 are going to be paying for the show, but what did Channel 4 think they were paying for?... TGBBO is a format, the music, the set design, the title, the sections, the format is the concept Channel 4 are paying for.  Indeed it was a little farcical recently when Jordon here appeared on BBC Radio Nottingham, but they couldn't play the theme tune to the show as the BBC don't have the rights.

But were Channel 4 paying for this format, for the crew of camera, set and sound operatives of so many shapes and sizes?... Or where they bidding for the whole package, where they bidding for Mel & Sue, with Mary & Paul?  I think they were.

I think there may very well be some squeaky bums over at Channel 4 towers right now, as they realise that not only have they potentially ruined the show, but that the millions whom will be tuned into slate the very hard acts to follow.

Paul Hollywood has, as yet, to comment on his position.  Jordon assures me he's not as dour as he is portrayed in the shows editing, he's a quite bright, funny guy.... I of course know this, not for his cakes or bread, but for his excellent taste in dogs (Labradors)... I'd like to think his announcement has not come because he will stick with the Beeb, and he has allowed, in his gentlemanly way, ladies to go first.  But he may just be wasting the cash register light up as more dough is coughed up for his approval and perhaps the last shred of a link to what was "The Great British Bake Off".


Addendum: Nope, seems Paul went with the Money... Humpf, gallantry is not in the pantry.

Monday, 19 September 2016

Dell Poweredge 2950 Perc 5/i RAID Controller RAM Fixes

Over the last few weeks you will have seen that I've been tinkering with my Dell Poweredge servers, I asked Morten over at "My Playhouse", his suggestion was that the RAID controllers should appear in the POST screens even if they had no RAM.

Mine were not appearing, however, whilst investigating Mortens suggestion I did try a different stick of RAM in one of the controllers, and it showed up!... The Dell Perc 5/i controller output light blue/cyan coloured text when it had an issue.

So, I did a lot of reading, and it's few and far between about exactly what RAM the controller should take... As I had HP marked RAM in a Dell RAID controller, it was clear somewhere in it's life this stick I have had been swapped out.

I read that I needed EEC DDR2 PC3200-R 333mhz RAM for the controller, and specifically they needed to be Rx8 or Rx16 types.

Luckily I recently had a donation directly to the blog, so I invested that kind gift into two second-hand sticks of RAM for the RAID controller... Here is the result:



Saturday, 17 September 2016

Tuesday, 13 September 2016

Software Engineering : C++14 Factory Create Pattern

For the GCC version of this, see this post (at the time of writing this link is to a scheduled item, it may not work just yet, scheduled for Tuesday 4th October 2016 at 18:30 GMT+1).

I commonly employ a "Factory Create" style to my classes in C++, the reason being I like to take control over the specific way that classes can be created, rather than relying on the compiler to always create the default constructors for me.  I like the constructors, but it leads to the problem of memory leaks, lets take a look at a bad example:


With this class any programmer can then do:

Alpha* l_somevalue = new Alpha(42);

They can then forget to call "delete l_somevalue;" and therefore leak memory.

We would therefore like to hide the constructors away, to prevent their miss use:


This necessitates we do expose someway to create an instance of the class, and that instance be wrapped as a smart pointer...


The first thing we see is a forward declaration of the class, then it's type wrapped as a smart pointer (a shared pointer in this case).  Next we see the various constructors have been made public, curing and removing all possibility of the programmer leaving hanging pointers to instances of our class.

Finally, we see a set of static "create" functions, our method to create an instance of the class now would look like this:

BetaPtr l_instance = Beta::Create();

When the reference count to the l_instance copy drops to zero then it will be automatically cleaned up, this is the whole point of this programming pattern.

There is nothing wrong with this code at the moment, we can define the constructors, knowing they can't be used outside the class, like this:


And the create functions look like this:


So far, we've learned nothing new... So what is new?... Well in C++14, really we should not be calling "new" at all.  The moment we see new outside the class we should implement this whole code pattern to hide the constructors away, exposing only smart pointers.  And likewise internally to those create functions we should not be calling "new", we should be using "std::make_shared".

Like this:


The problem?...


Hmmm... "error C2248: 'Beta::Beta': cannot access private memory declared in class 'Beta'", what is this telling us?

That the constructor of Beta could not access one of the private members of itself?  Huh?.. That makes no sense, of course the constructor should be able to access its own member!

What else does the error tell us?  "File: memory"... memory?... Not my code file, but the memory header?  We can open that location and take a look, what is the location of the error representing?


The _Ref_count_obj, the actual location that a shared_ptr is instantiated and the forward passed the arguments to the constructor, so the error is NOT that the constructor of our class can't get at it's private member, but that the template wrapped reference count object, which we inherit from because of the use of "make_shared", that reference can't get at the private members of the class!

How to solve this?... Simple:


Simply adding the "friend std::_Ref_count_obj<Beta>" allows that inherited class from "<memory>" to see inside the private area of the Beta class, and we enable the clean use of std::make_shared thereafter.

I highly recommend removing your constructors from prominence, and the use of "Factory Creation", as to other much more authoritative figures then myself.

My Complete code is below!

#include <iostream>
#include <memory>


class Alpha
{
private:

int m_AlphaValue;

public:

Alpha();
Alpha(const int& p_NewValue);
Alpha(const Alpha& p_OtherAlpha);

const int Value();
void Value(const int& p_NewValue);
};



class Beta;
using BetaPtr = std::shared_ptr<Beta>;
class Beta
{
private:

friend std::_Ref_count_obj<Beta>;

int m_AlphaValue;

Beta();
Beta(const int& p_NewValue);
Beta(const Beta& p_OtherBeta);

public:

static BetaPtr Create();
static BetaPtr Create(const int& p_NewValue);
static BetaPtr Create(const BetaPtr& p_OtherBeta);

const int Value();
void Value(const int& p_NewValue);
};


Beta::Beta()
:
m_AlphaValue(42)
{
}

Beta::Beta(const int& p_NewValue)
:
m_AlphaValue(p_NewValue)
{
}

Beta::Beta(const Beta& p_OtherBeta)
:
m_AlphaValue(p_OtherBeta.m_AlphaValue)
{
}

BetaPtr Beta::Create()
{
return std::make_shared<Beta>();
}

BetaPtr Beta::Create(const int& p_NewValue)
{
return std::make_shared<Beta>(p_NewValue);
}

BetaPtr Beta::Create(const BetaPtr& p_OtherBeta)
{
return std::make_shared<Beta>(*p_OtherBeta.get());
}




int main()
{
Alpha* l_Instance = new Alpha(42);
std::cout << "Alpha: " << l_Instance->Value() << std::endl;

BetaPtr l_BetterInstance = Beta::Create(42);
std::cout << "Beta: " << l_BetterInstance->Value() << std::endl;

// No need to delete l_BetterInstance, it cleans itself up

// Whoops... l_Instance of alpha leaks!
}

Monday, 12 September 2016

From Ubuntu Server to Debian...

I have had a few issues with Ubuntu's 16.04 release, notably on the server side, when removing the physical network wire on one connection, it would stay connected on another, reconnecting the wire it'd not come back up.

I tried this with wireless connections, with physical RJ45 and virtual devices in various guises, none of them worked right for my needs.

And loathed as I am to change to anything else, I'm currently in the middle of setting up and using a new purely Debian based server... Watch this space....


Friday, 9 September 2016

Story Time : Fantastic Rack Mount Mistakes #3

Technically this is not a rack mounted mistake, but it was a mistake made by someone with a rack mounted unit.  A loooooooottttttttt of years ago, around the turn of the millennium in fact, I worked at a company where they used a Windows 2000 Server to collect a series of information, from memory, I think it ran Websphere and Jakarta Tomcat as middleware, connecting to a Microsoft SQL Server back end.

This server gave me nothing but trouble, I had to bring it down to publish new software to it, then bring it all back up again, because of some wierdness, and worst of all, I was only a user on the machine, I never saw it, was never in the same room as it, it was hosted in a data centre far away from me.

Remoting into it on late 1990's internet (because they'd not upgraded) was painful at 14kpbs, so much so that connecting to it from home was easier, where I had the first generation "Diamond Cable" (later NTL, later Virgin) broadband... at a blistering 512Kbps.

The main problem was, I needed someway to get the server to tell me it's IP, it could change, and the network guy at work used to handle this by crystal ball gazing, and copying the new IP into an e-mail and sending it to everyone.  Of course at home, I didn't get my work mail... Humpf.

The system however was all just Java, and after about 18 months I got the chance to move up the suckling chain of management within the project, and I immediately pointed out to the directors that we could drop all this Windows stuff, and the expensive licensing, by going to this new system called "Linux".

As a result I ended up at an open day presentation in the middle of Birmingham, with speakers from RedHat and Suse.  The talks were pointless, the guy from RedHat wore a T-shirt saying "Suse is shite", and the guy from Suse wore a suit and talked about professionalism; not very constructive, it all wanted to pull the admins in the room into the "are you a pro, or are you a hacker" division.  Neither talked about the distribution.

I therefore decided to learn about Linux myself, and I started a new server, initially just an old Pentium II machine with 32Mb of RAM, it was soon found to be a little bit better and a hell of a lot cheaper than the Windows Server, so I got a new shiny machine (my first commercial rack mounted server, I forget the model, I'm pretty sure it was a Compaq, as I'd seen the Proliant at my previous place of work and think I told the boss to get one).

This machine arrived, and it ran seamlessly pretty much from the get go, as had a couple of disk deaths in it's time, but there was no problem with it.

With the problem of it being in the remote location however, I had a trick, I created a script, like this:

ifconfig > config.txt
traceroute www.bbc.co.uk >> config.txt
cat config.txt | mail -s BootMail xelous@hotmail.co.uk
rm config.txt

The result?... I had it send me a mail whenever it reset, so I got the IP information, and a trace route listing to the outside world (I think the original place I used to trace route to was Altavista!  And it didn't go to hotmail, it went to my old NTL provided e-mail address.

What's the mistake here?... Well, that NTL e-mail address linked to my virgin e-mail address, which forwarded to my MSN address, which turned into Hotmail.

And... You may have guessed it... The other day, that very server was turned on somewhere, somehow... It had a network connection, was powered on, and it sent me a mail!

It was in Worcestershire, I think, and I could still SSH into it!

I changed the daily greeting to tell them they're server is insecure, disabled the script which was e-mailing me, and this pretty much ends our story.

The failure?  Don't plug things into your network, into your rack, unless you know what they're trying and going to do.  EVER!