Click here to Skip to main content
15,895,799 members
Articles / All Topics
Technical Blog

Z80 CPU - Double Byte Opcodes and low order Bytes

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
18 May 2016CPOL3 min read 6.7K   1  
In a previous post I mentioned that all Opcodes were a single Byte.
In a previous post I mentioned that all Opcodes were a single Byte. It turns out I was mistaken and that a number of instructions actually have Opcodes made up of two Bytes.

One such instruction is the LD IX, nn instruction which means that a constant value should be loaded into the IX Register.

The IX Register is a 16 Bit Register and is used for indexing.

Unfortunately I have no way of outputting the value of the this operation so we are in the same situation we were when we first started.

So instead I am going to start with the LD (nn), IX Instruction which means output the value of the IX register to a defined address. But life is never that simple,

The IX register is a 16 bit register but each memory address only holds one byte. So instead we have to introduce the concept of low and high order bytes.

The low order byte of a byte pair is the byte that contains the least significant bits and the high order byte contains the most significant bits. The most significant bit is the bit which adds the highest value onto the resulting value.

If we have a 2 bit Structure we can set each of the bits. The high order bit has a value of two whereas the low order bit has a value of one. The same concept applies to high and low bytes.

So now that we understand the difference between the high and low order bytes we can look at saving the two bytes to memory.

We do this by saving the low order byte to the memory location specified by (nn) and then the high order byte to the memory location specified by (nn + 1).

The test for this is

        [TestMethod]<br />        public void Load0hOutOfIXRegisterToAddress()<br />        {<br />            var memory = new ListOfActionsMemory();<br />            var cpu = new CPU(memory);<br /><br />            var lowAddressByte = new ZByte(Bit.Zero, Bit.One, Bit.Zero, Bit.Zero, Bit.One, Bit.One, Bit.One, Bit.Zero);<br />            var highAddressByte = new ZByte(Bit.One, Bit.One, Bit.Zero, Bit.One, Bit.One, Bit.One, Bit.Zero, Bit.Zero);<br /><br />            var secondLowAddressByte = new ZByte(Bit.Zero, Bit.One, Bit.Zero, Bit.Zero, Bit.One, Bit.One, Bit.One, Bit.One);<br /><br />            var address = new SixteenBitAddress(highAddressByte, lowAddressByte);<br />            var secondAddress = new SixteenBitAddress(highAddressByte, secondLowAddressByte);<br /><br />            cpu.PerformInstruction(LoadCommand.IXintoNN_First, LoadCommand.IXintoNN_Second, lowAddressByte, highAddressByte);           <br /><br />            Assert.AreEqual(address, memory.Saved[0].Item1);<br />            Assert.AreEqual(new ZByte(), memory.Saved[0].Item2);<br /><br />            Assert.AreEqual(secondAddress, memory.Saved[1].Item1);<br />            Assert.AreEqual(new ZByte(), memory.Saved[1].Item2);<br />        }<br />
But in doing this we have found a weakness in my approach of defining each Bit separately, and that is Math.

I still think that having an external interface to the ZByte is a good idea but the effort of performing binary mathematics seems to be a waste. So instead I am going to change the internal representation of the Zbyte to be a System.Byte which makes the math part really easy but leave the external interface the same.

Once this has been solved we can continue similar to before by loading a constant value into the register and testing that the correct values are loaded in to memory.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --