Most tricks come from either [Jeff's GB Assembly Code Tips v1.0](http://www.devrs.com/gb/files/asmtips.txt), or [the page on Z80 Optimization on WikiTI](http://wikiti.brandonw.net/index.php?title=Z80_Optimization) ## Registers ### Set A to zero ```asm ld a, 0 ; 2 bytes, 2 cycles, no changes to flags ;;; xor a ; 1 byte, 1 cycle, sets flags C to 0 and Z to 1 sub a ; 1 byte, 1 cycle, sets flags C to 0 and Z to 1 ``` ### Set A to some constant subtracted by A ```asm ld b,a ; 4 bytes, 4 cycles ld a,CONST sub b ;;; cpl ; 3 bytes, 3 cycles add CONST+1 ``` ### Add A to HL ```asm add l ; 6 bytes, 6 cycles ld l, a ld a, 0 adc h ld h,a ;;; add l ; 5 bytes, 5 cycles ld l, a jr nc, .NoCarry inc h .NoCarry: ``` ### Loading from an offset to HL ```asm ld a, [offset] ; 8 bytes, 10 cycles ld l, a ld a, [offset+1] ld h, a ;;; ld hl, offset ; 6 bytes, 8 cycles ld a, [hli] ld h, [hl] ld l, a ``` ### Exchanging HE and DL ```asm ld a,d ; 6 bytes, 6 cycles ld d,h ld h,a ld a,e ld e,l ld l,a ;;; push de ; 4 bytes, 9 cycles ld d,h ld e,l pop hl ``` ## Branching ### Compare A to zero ```asm cp 0 ; 2 bytes, 2 cycles ;;; or a ; 1 byte, 1 cycle and a ; 1 byte, 1 cycle ``` ### Compare A-1 to zero ```asm cp 1 ; 2 bytes, 2 cycles ;;; dec a ; 1 byte, 1 cycle, decrements a ``` ## Functions ### Tail call optimization ```asm call Function ; 4 bytes, 10 cycles ret ;;; jp Function ; 3 bytes, 4 cycles ``` ## Executing subroutines ```asm ld hl, param1 call Function1 ld hl, param2 call Function2 ld hl, param3 call Function1 ... ... .Function1: ... ret .Function2: ... ret ;;; ld sp, calltable ret ; jump to sp (first entry on calltable) .Function1: pop hl ... ret .Function2: pop hl ... ret calltable: dw Function1, param1 dw Function2, param2 dw Function1, param3 ``` ### Calling HL ```asm ld de, .retadr ; 5 bytes, 8 cycles push de jp [hl] .retadr: ... ;;; call DoJump ; 4 bytes, 7 cycles ... DoJump: jp [hl] ```