{"id":764,"date":"2025-05-18T19:24:32","date_gmt":"2025-05-18T09:24:32","guid":{"rendered":"http:\/\/electricadventures.net\/?p=764"},"modified":"2025-05-18T19:24:32","modified_gmt":"2025-05-18T09:24:32","slug":"lets-make-a-retro-game-ep-5-starting-z80-assembly","status":"publish","type":"post","link":"https:\/\/electricadventures.net\/?p=764","title":{"rendered":"Lets Make a Retro Game Ep 5: Starting Z80 Assembly"},"content":{"rendered":"\n<p>In this episode, we are going to go over the basics of Z80 assembler.\u00a0<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"689\" src=\"http:\/\/electricadventures.net\/wp-content\/uploads\/2025\/05\/image-126-1024x689.png\" alt=\"\" class=\"wp-image-765\"\/><\/figure>\n\n\n\n<p>This will not be a full tutorial on Z80 assembler as that would require a series in its own right, but hopefully should give you a start so you can follow on with the rest of this series, whilst doing some learning from suggested resources.<\/p>\n\n\n\n<p>The video associated with this episode is located here:<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"Lets Make A Retro Game - Episode 5 - Starting Z80 Assembler\" width=\"960\" height=\"540\" src=\"https:\/\/www.youtube.com\/embed\/TEwkHxDm9WY?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<p>Now, while we are on suggested resources, for Z80, there is no better than \u201cProgramming The Z80\u201d by Rodney Zaks (ISBN: 0-89588-047-4).<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Memory and Registers<\/h1>\n\n\n\n<p>Programming is all about moving ones and zeroes from one location to another in the computer\u2019s memory.<\/p>\n\n\n\n<p>The Z80 processor, like most processors, has two different ways to store information:<\/p>\n\n\n\n<p>\u00b7<strong>Registers<\/strong> \u2013 These are the processor&#8217;s internal memory locations that are used for doing calculations like addition and subtraction.\u00a0They are located inside the processor itself, so they are the quickest place for the processor to access information<\/p>\n\n\n\n<p>\u00b7<strong>Memory<\/strong> \u2013 So this is the actual RAM memory that the computer or console has. This is a lot larger, but is located outside the processor, so more time is required to read and write something to a memory location.<\/p>\n\n\n\n<p>Being an 8-bit processor, the Z80\u2019s standard registers store 8 bits of information, i.e. they can each hold a value from 0-255.<\/p>\n\n\n\n<p>The names of the 8-bit registers are:<\/p>\n\n\n\n<p>\u00b7<strong>A<\/strong>&nbsp;is also called the &#8220;accumulator&#8221;. It is the primary register for arithmetic operations and accessing memory.<\/p>\n\n\n\n<p>\u00b7<strong>B<\/strong>&nbsp;is commonly used as an 8-bit counter.<\/p>\n\n\n\n<p>\u00b7<strong>C<\/strong>&nbsp;is used when you want to interface with hardware ports.<\/p>\n\n\n\n<p>\u00b7<strong>D<\/strong>\u00a0is not normally used in its 8-bit form. Instead, it is used in conjunction with E.<\/p>\n\n\n\n<p>\u00b7<strong>E<\/strong>\u00a0is again not used in its 8-bit form.<\/p>\n\n\n\n<p>\u00b7<strong>F<\/strong>&nbsp;is known as the flags. It is the one register you cannot mess with on the byte level.<\/p>\n\n\n\n<p>\u00b7<strong>H<\/strong>&nbsp;is another register not normally used in 8-bit form.<\/p>\n\n\n\n<p>\u00b7<strong>L<\/strong>&nbsp;is yet another register not normally used in 8-bit form.<\/p>\n\n\n\n<p>\u00b7<strong>I<\/strong>&nbsp;is the interrupt vector register.<\/p>\n\n\n\n<p>\u00b7<strong>R<\/strong>&nbsp;is the refresh register. Although it holds no specific purpose to the OS, it can be used to generate random numbers.<\/p>\n\n\n\n<p>\u00b7<strong>IXH<\/strong>&nbsp;The higher (first) byte of the IX register. Note that&nbsp;<em>I<\/em>&nbsp;is&nbsp;<strong>not<\/strong>&nbsp;the higher byte of IX. Combines with IXL to make the IX register.<\/p>\n\n\n\n<p>\u00b7<strong>IXL<\/strong>\u00a0The lower (second) byte of the IX register. When combined with IXH, these two registers make up the IX register.<\/p>\n\n\n\n<p>\u00b7<strong>IYH<\/strong>&nbsp;Again, this is the higher byte of the IY register. Note that IYH is different from both&nbsp;<em>I<\/em>&nbsp;and&nbsp;<em>IXH<\/em>. Combines with IYL to make the IY register.<\/p>\n\n\n\n<p>\u00b7<strong>IYL<\/strong>&nbsp;The lower byte of the IX register. Combines with IYH to make the IY register.<\/p>\n\n\n\n<p>But unlike other 8-bit processors, the Z80 can also treat pairs of registers as a single 16-bit value, i.e. they can each hold a value from 0-65535:<\/p>\n\n\n\n<p>\u00b7<strong>AF<\/strong>&nbsp;is not normally used because of the F, which is used to store flags.<\/p>\n\n\n\n<p>\u00b7<strong>BC<\/strong>\u00a0is used by instructions and code sections that operate on streams of bytes as a byte counter. Is also used as a 16-bit counter.<\/p>\n\n\n\n<p>\u00b7<strong>DE<\/strong>&nbsp;holds the address of a memory location that is a destination.<\/p>\n\n\n\n<p>\u00b7<strong>HL<\/strong>\u00a0The general 16-bit register, it&#8217;s used pretty much everywhere you use 16-bit registers. Its most common uses are for 16-bit arithmetic and storing the addresses of stuff (strings, pictures, labels, etc.). Note that HL usually holds the original address while DE holds the destination address.<\/p>\n\n\n\n<p>\u00b7<strong>PC<\/strong>\u00a0The program counter. It holds the point in memory that the processor is executing code from. No function can change the PC except by actually jumping to a different location in memory.<\/p>\n\n\n\n<p>\u00b7<strong>SP<\/strong>&nbsp;The stack pointer. It holds the current address of the top of the stack.<\/p>\n\n\n\n<p>\u00b7<strong>IX<\/strong>\u00a0is called an index register. Its use is similar to HL, but its use should be limited as it has other purposes, and also runs slower than HL.<\/p>\n\n\n\n<p>\u00b7<strong>IY<\/strong>&nbsp;is another index register. It holds the location of the system flags and is used when you want to change a certain flag. For now, we won&#8217;t do anything to it.<\/p>\n\n\n\n<p>As you can see the Z80 actually has quite a lot of registers, all used for different things, which can get a little confusing.&nbsp;<\/p>\n\n\n\n<p>The number of registers makes it easier to do certain tasks than other chips with smaller instruction sets, e.g. 6502.\u00a0But you have to know which ones you can use for different tasks, so if unsure, just check online or in the referenced book.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Moving Things Around<\/h1>\n\n\n\n<p>Hopefully, your head is not spinning too hard after that very wordy section, and we can get onto the more practical parts of this episode.<\/p>\n\n\n\n<p>There is one instruction for moving something to and from memory or a register, and it\u2019s called:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>LD &lt;target&gt;, &lt;source&gt;<\/code><\/pre>\n\n\n\n<p>\u00b7&lt;target&gt; This is where the information will end up.<\/p>\n\n\n\n<p>\u00b7&lt;source&gt; This is where the information comes from.<\/p>\n\n\n\n<p>In general terms, each of the &lt;target> or &lt;source> fields can be either a register, a memory location or an actual direct value.<\/p>\n\n\n\n<p>If it is a register, then you just put the name of the register, e.g.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>LD A,5<\/code><\/pre>\n\n\n\n<p>This will put the value 5 in the accumulator.<\/p>\n\n\n\n<p>But you can also specify a memory location, e.g.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>LD A,($C000)<\/code><\/pre>\n\n\n\n<p>This will get the contents of the memory location C000h and put it in the accumulator.<\/p>\n\n\n\n<p>If you wanted to calculate the memory location, you can use some of the 16-bit registers, e.g.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>LD HL,$C000\nLD A,(HL)<\/code><\/pre>\n\n\n\n<p>So this example does the same thing as our previous statement, but of course, we can control the memory location by changing the value in HL.<\/p>\n\n\n\n<p>Most of the statements so far can work the other way around as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>LD ($C000),A<\/code><\/pre>\n\n\n\n<p>Save the value in the accumulator in the memory location C000h.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>LD HL,$C000\nLD (HL),A<\/code><\/pre>\n\n\n\n<p>Save the value in the accumulator in the memory location indicated by the HL register.<\/p>\n\n\n\n<p>There are lots of combinations here, and you can do quite a few of them with most of the registers, but not all, so just check any of the online guides or the suggested book for more details.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Let\u2019s Do Some Maths<\/h1>\n\n\n\n<p>Now, to round out this episode, let\u2019s do something with some numbers and do some basic maths.<\/p>\n\n\n\n<p>All maths is based around addition, subtraction and manipulation of bits.\u00a0For this quick look, we will do some simple addition and subtraction to get you started.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Addition<\/h2>\n\n\n\n<p>To add two 8-bit numbers together, we have to use the accumulator as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ADD A,&lt;source&gt;<\/code><\/pre>\n\n\n\n<p>&lt;source&gt; can be a direct value, another 8-bit register, or a memory location pointed to by HL e.g.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>; setup our values\nLD A,5\nLD HL,$C000\nLD (HL),A\nLD A,0\nLD B,5\n\n; now do our maths\nADD A,5\nADD A,B\nADD A,(HL)<\/code><\/pre>\n\n\n\n<p>So in this example, each ADD statement would in fact add 5 to the current value in the accumulator, so at the end it would contain a value of 15.<\/p>\n\n\n\n<p>Now, if you want to do 16-bit maths, HL takes the part of the accumulator as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>LD HL,$C000\nLD DE,$1000\nADD HL,DE<\/code><\/pre>\n\n\n\n<p>This would result in HL containing D000h.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Subtraction<\/h2>\n\n\n\n<p>To subtract one 8-bit number from another, we have to use the accumulator as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SUB 5\nSUB B\nSUB (HL)<\/code><\/pre>\n\n\n\n<p>Notice there is no mention of the accumulator, as this statement only works on the accumulator.\u00a0Less typing, but it can be a bit confusing.<\/p>\n\n\n\n<p>Now, to do the same thing for 16 bits, we have to use a different statement as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>LD HL,$C000\nLD DE,$1000\nOR A\nSBC HL,DE<\/code><\/pre>\n\n\n\n<p>This statement stands for \u2018Subtract with Carry\u2019 so I have added an extra statement, OR A, which will OR the value of the accumulator with itself, which does nothing to the value but does clear the carry flag.<\/p>\n\n\n\n<p>This will result in HL containing B000h.&nbsp;<\/p>\n\n\n\n<p>SBC can also be used with the accumulator for 8-bit maths, where you want to include the carry flag set by something else (beyond the scope of this article).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Increasing and Decreasing<\/h3>\n\n\n\n<p>One more type of adding and subtracting is to increment or decrement a value by one.\u00a0Now, this of course could be done by just adding or subtracting the value one using the statements we have looked at above, but to save both instruction space and speed, most processors have instructions to do this directly.<\/p>\n\n\n\n<p>The Z80 versions work as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>INC &lt;register>\nINC (HL)\nDEC &lt;register>\nDEC (HL)<\/code><\/pre>\n\n\n\n<p>So these will increment or decrement either a single register (8 or 16-bit) or a memory location pointed to by HL.<\/p>\n\n\n\n<p>Once again, this is not supported by all registers.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this episode, we are going to go over the basics of Z80 assembler.\u00a0 This will not be a full tutorial on Z80 assembler as that would require a series in its own right, but hopefully should give you a start so you can follow on with the rest of this series, whilst doing some<\/p>\n","protected":false},"author":1,"featured_media":765,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[62],"tags":[],"class_list":["post-764","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-lets-make-a-retro-game"],"acf":[],"_links":{"self":[{"href":"https:\/\/electricadventures.net\/index.php?rest_route=\/wp\/v2\/posts\/764","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/electricadventures.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/electricadventures.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/electricadventures.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/electricadventures.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=764"}],"version-history":[{"count":1,"href":"https:\/\/electricadventures.net\/index.php?rest_route=\/wp\/v2\/posts\/764\/revisions"}],"predecessor-version":[{"id":766,"href":"https:\/\/electricadventures.net\/index.php?rest_route=\/wp\/v2\/posts\/764\/revisions\/766"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/electricadventures.net\/index.php?rest_route=\/wp\/v2\/media\/765"}],"wp:attachment":[{"href":"https:\/\/electricadventures.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=764"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/electricadventures.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=764"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/electricadventures.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=764"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}