# Z80 assembly

[Courses](https://asm-editor.specy.app/learn/courses.md) › Z80 assembly

Web page: https://asm-editor.specy.app/learn/courses/z80

> Write Z80 programs with loops, arrays and subroutines, then use I/O ports for graphics, keyboard input and sound.

By Specy

This course is about the Zilog Z80, and about writing programs for it.

If you have never written assembly before, read
[Assembly basics](https://asm-editor.specy.app/learn/courses/assembly-basics.md) first. It covers registers, memory, branching, the
stack and the rest once and quickly, to give you the ideas. This course takes all of that for
granted and goes over the same ground again in much more depth, on one machine.

The Z80 is an 8 bit CPU. Its registers hold one byte each, they pair up into 16 bit registers when an
address is needed, and a value too big for a register is the ordinary case here, not the exception.

## Introduction

- [Getting started with the Z80](https://asm-editor.specy.app/learn/courses/z80/introduction/getting-started.md): Meet the Z80, see what assembly language does, and try a small program in the browser editor.
- [Registers, pairs and the shadow set](https://asm-editor.specy.app/learn/courses/z80/introduction/registers-pairs-and-the-shadow-set.md): Meet the seven byte registers, use bc, de and hl as two-byte pairs, read and write memory through hl, and swap the pairs with their shadow copies.
- [The 64 KB address space](https://asm-editor.specy.app/learn/courses/z80/introduction/the-64-kb-address-space.md): Explore the Z80's 64 KB address map, read and write bytes at fixed addresses, and see how two-byte values are stored in little-endian order.
- [org, db, dw and ds](https://asm-editor.specy.app/learn/courses/z80/introduction/org-db-dw-and-ds.md): Place code and data with .org, write bytes and words with .db and .dw, reserve space with .ds, and name values with equ.
- [Bytes and 16-bit pairs](https://asm-editor.specy.app/learn/courses/z80/introduction/bytes-and-16-bit-pairs.md): Byte ranges and signed readings, wraparound, 16-bit pair addition, and widening an unsigned byte into a pair.
- [The Z80 instruction set](https://asm-editor.specy.app/learn/courses/z80/introduction/the-z80-instruction-set.md): Read Z80 instructions as mnemonics and operands, see how the assembler encodes them as bytes, and use ldir to copy a run of memory.
- [Addressing on the Z80](https://asm-editor.specy.app/learn/courses/z80/introduction/addressing-on-the-z80.md): How Z80 operands name immediate values, registers, memory through an address in a pair, and memory at a fixed labelled address.
- [The F register](https://asm-editor.specy.app/learn/courses/z80/introduction/the-f-register.md): Meet the F register through the zero and carry flags. Use cp and or to set them, inspect them in the flags panel, and learn how long a comparison result lasts.
- [Memory regions and executable files](https://asm-editor.specy.app/learn/courses/z80/introduction/memory-regions-and-executable-files.md): Map Z80 code, data and reserved space with familiar directives, and distinguish memory addresses from positions in executable files.

## Think in assembly

- [jp, jr and the conditions](https://asm-editor.specy.app/learn/courses/z80/think-in-assembly/jp-jr-and-the-conditions.md): Use flags from a comparison or zero test to choose the next instruction with conditional and unconditional jp or jr.
- [Loops and djnz](https://asm-editor.specy.app/learn/courses/z80/think-in-assembly/loops-and-djnz.md): Use a backward jump to repeat a block of instructions, then djnz to count down in b and jump in one step. Learn its zero-count edge case and a guard for a count that may be zero.
- [8-bit and 16-bit arithmetic, logic and bits](https://asm-editor.specy.app/learn/courses/z80/think-in-assembly/arithmetic-logic-and-bits.md): Byte arithmetic through the accumulator, bitwise logic and masks, the three single-bit instructions, shifts, and 16-bit pair arithmetic. Learn how the carry flag both records a result and joins byte-sized pieces into a wider calculation.
- [Arrays, strings and ix](https://asm-editor.specy.app/learn/courses/z80/think-in-assembly/arrays-strings-and-ix.md): Lay out byte and word arrays, walk zero-terminated strings, and use ix with named fixed offsets for records.
- [The stack, push and pop](https://asm-editor.specy.app/learn/courses/z80/think-in-assembly/the-stack-push-and-pop.md): Use the stack's two-byte items in last-in, first-out order. Trace push and pop byte by byte, save pairs around work, and keep the stack balanced.
- [call, ret and passing values](https://asm-editor.specy.app/learn/courses/z80/think-in-assembly/call-ret-and-passing-values.md): How call and ret use the stack, how a subroutine contract passes values and preserves registers, and how ix gives stack arguments stable offsets.

## Talking to the outside world

- [Ports: in and out](https://asm-editor.specy.app/learn/courses/z80/talking-to-the-outside-world/ports-in-and-out.md): Use the Z80's separate I/O space with in and out. Print characters and numbers, read console input, and pass a 16-bit value through the playground's word port.
- [The screen, keyboard and mouse through ports](https://asm-editor.specy.app/learn/courses/z80/talking-to-the-outside-world/screen-keyboard-and-mouse.md): Draw shapes and complete animation frames through Screen ports, then poll held keys and mouse state with the register-selected input form.
- [Interrupts: im, ei, di and halt](https://asm-editor.specy.app/learn/courses/z80/talking-to-the-outside-world/interrupts-im-ei-di-and-halt.md): How a Z80 accepts an interrupt, waits with halt, preserves interrupted state and chooses a handler with interrupt modes 0, 1 and 2.

## Examples

- [Moving values around](https://asm-editor.specy.app/learn/courses/z80/examples/moving-values.md): Two numbers in registers, added and doubled into a perimeter, with the answer read in the registers panel.
- [Variables in memory and constants](https://asm-editor.specy.app/learn/courses/z80/examples/variables-in-memory.md): Add two words from memory and an assembler constant, then inspect the word written back as the total.
- [The bigger of two numbers](https://asm-editor.specy.app/learn/courses/z80/examples/if-else.md): Borrow flags and conditional jumps choose the larger unsigned value and turn a subtraction into a distance.
- [Fill an array with the numbers from 1 to 10](https://asm-editor.specy.app/learn/courses/z80/examples/counting-loop.md): Use djnz to fill a reserved array of ten bytes, moving a pointer one byte at a time and reading the result in the memory panel.
- [Sum of an array](https://asm-editor.specy.app/learn/courses/z80/examples/sum-of-an-array.md): Six bytes in memory, added with a pointer that steps through the array and leaves the total in a.
- [The largest element](https://asm-editor.specy.app/learn/courses/z80/examples/max-of-an-array.md): Find the largest signed byte and its index, using the sign and overflow flags to make each comparison.
- [Length of a string](https://asm-editor.specy.app/learn/courses/z80/examples/string-length.md): Walk to a string's zero byte and subtract its starting address to find its length.
- [Reverse a string in place](https://asm-editor.specy.app/learn/courses/z80/examples/reverse-a-string.md): Scan a zero-terminated string, then use two pointers and a counted loop to swap its outer bytes in place.
- [Multiply and divide, with the remainder](https://asm-editor.specy.app/learn/courses/z80/examples/multiply-and-divide.md): Multiply by testing and adding bits, then divide one bit at a time to find both the quotient and remainder.
- [Even or odd, count the set bits, multiply by shifting](https://asm-editor.specy.app/learn/courses/z80/examples/bit-tricks.md): Four questions about one byte answered with a bit test, three doublings of a pair, a mask and a loop that reads the carry flag.
- [A subroutine with its arguments in registers](https://asm-editor.specy.app/learn/courses/z80/examples/subroutine-with-register-arguments.md): Find the greatest common divisor of two positive bytes using a subroutine with register arguments and a return value.
- [Stack arguments and a stack frame](https://asm-editor.specy.app/learn/courses/z80/examples/subroutine-with-stack-arguments.md): Pass two arguments on the stack, use ix to reach them, and keep a local value across another call.
- [Recursion: factorial and Fibonacci](https://asm-editor.specy.app/learn/courses/z80/examples/factorial-and-fibonacci.md): Trace factorial and Fibonacci calls as saved values and return addresses move on the stack, then see where a 16-bit result overflows.
- [Bubble sort](https://asm-editor.specy.app/learn/courses/z80/examples/bubble-sort.md): Sort eight bytes in place with neighbouring comparisons and swaps, using c for passes and b for each djnz-controlled inner loop.
- [A jump table](https://asm-editor.specy.app/learn/courses/z80/examples/jump-table.md): Use an index to read one of four code addresses from memory, then jump to it with jp (hl).
- [Binary search](https://asm-editor.specy.app/learn/courses/z80/examples/binary-search.md): Search twelve ascending unsigned bytes by halving a half-open range; e receives the index or 0xFF, while the middle index is saved on the stack for address calculation.
- [A 2D array](https://asm-editor.specy.app/learn/courses/z80/examples/two-dimensional-array.md): Three rows of four words, one element reached by row and column, and a whole column added up by stepping ix a row at a time.
- [Print a string](https://asm-editor.specy.app/learn/courses/z80/examples/hello-world.md): Print a zero-terminated string one character at a time, then print a number through the decimal console port.
- [Read two numbers and print their sum](https://asm-editor.specy.app/learn/courses/z80/examples/sum-of-two-numbers.md): Two prompts that wait for you to type, the numbers coming back in a, and a total too big for a byte printed through the 16 bit port.
- [Print a number in any base without help](https://asm-editor.specy.app/learn/courses/z80/examples/number-to-string.md): The division routine run once per digit, a buffer filled backwards from its end, and the same number printed in base 16, 10 and 2.
- [Drawing shapes on the screen](https://asm-editor.specy.app/learn/courses/z80/examples/drawing-on-the-screen.md): A house, a sun and a sky drawn out of a table of shapes, one record per command, with colours packed into a byte and the label at the text cursor.
- [A bouncing ball](https://asm-editor.specy.app/learn/courses/z80/examples/bouncing-ball.md): A ball that turns round at all four edges, drawn off screen and shown a whole frame at a time, paced by the frame port instead of by how fast your machine is.
- [Move a square with the keyboard](https://asm-editor.specy.app/learn/courses/z80/examples/keyboard-control.md): The key state port polled once a frame for the four arrows, a direction kept in memory, and a square that keeps going until you steer it somewhere else.
- [The snake game](https://asm-editor.specy.app/learn/courses/z80/examples/snake.md): Build and play Snake with packed board cells, a body moved by a loop, keys polled every frame, pseudorandom food placement, and a score on the Screen and in the transcript.
- [Flappy ASM](https://asm-editor.specy.app/learn/courses/z80/examples/flappy-asm.md): A game with a state machine in it: three states, gravity counted in sixteenths of a pixel, a press that only counts on the frame it began, and pipes clipped by hand because a coordinate is one byte.
- [Play a tune](https://asm-editor.specy.app/learn/courses/z80/examples/play-a-tune.md): Play the first phrase of Ode to Joy from a table of pitches and durations, waiting for each note to end before starting the next.
- [Chiptune](https://asm-editor.specy.app/learn/courses/z80/examples/chiptune.md): Play a short tune on the MSX sound chip: a lead and a bass on two square-wave channels and noise drums struck by the envelope.

## Optional

- [The whole Z80 assembly course](https://asm-editor.specy.app/learn/courses/z80/llms-full.txt): every Lecture in order in one file, to search through
