Skip to content

Instantly share code, notes, and snippets.

@neuro-sys
Last active April 7, 2025 13:55
Show Gist options
  • Save neuro-sys/0d08b1af7fd033193d06 to your computer and use it in GitHub Desktop.
Save neuro-sys/0d08b1af7fd033193d06 to your computer and use it in GitHub Desktop.
Z80 If-Else Conditional Statements

Z80 If-Else Conditional Statements

Label Order and Structure

As usual, first write the if conditional statement in a higher level language like C.

if ( cond ) {
    /* statement */
}

Then put labels where statements and expressions go.

if ( cond ) {
    cond_body
}
cond_not

Enumerate them in their order of execution.

if ( [1] ) {
    [2]
}
[3]

Place the labels in your assembly code with respect to their order.

.cond
.cond_body
.cond_not
.cond
    ld      a, (ix-1)           ;; if ( a >= 79 )
    sub     79                  ;;
    jp      c, cond_not         ;; jump if carry set
.cond_body                      ;; then
    ld      (ix-3), -1          ;; b = -1
.cond_not                       ;; else

Strip the unnecessary labels if you feel like, and don't need them at the cost of readability.

    ld      a, (ix-1)  
    sub     79
    jp      c, cond_not
    ld      (ix-3), -1 
.cond_not 

Conditional Instructions

C subtraction uint int
if (a >= b) if (a-b >= 0) jp c jp po
if (a < b) if (a-b < 0) jp nc jp pe
if (a == b) if (a-b == 0) jp nz jp nz

All With an Example

    org &8000

scr_next_line       equ &bc26
txt_output          equ &BB5A
scr_set_mode        equ &bc0e
scr_set_ink         equ &bc32
scr_set_border      equ &bc38

.savestack  defs 2

.start
    push    af                  ;; save all registers
    push    bc                  ;;
    push    de                  ;;
    push    hl                  ;;
    push    ix                  ;;
    push    iy                  ;;
    ld      (savestack), sp     ;; save SP

    ld      sp, stack           ;; initialize SP

    ld      a, 0
    ld      b, 0
    ld      c, 0
    call    scr_set_ink

    ld      a, 1
    ld      b, 26
    ld      c, 26
    call    scr_set_ink

    ld	    b, 0
    ld      c, 0
    call    scr_set_border

    ld      a, 2
    call    scr_set_mode

    call    makeScreenAddrTable

    call    effect1

    ld      sp, (savestack)
    pop     iy                  ;; restore all registers
    pop     ix                  ;;
    pop     hl                  ;;
    pop     de                  ;;
    pop     bc                  ;;
    pop     af                  ;;

    ret                         

.effect1
    push    ix
    ld      ix, 0
    add     ix,sp

    ld      hl, -6              ;; x, y, xDir, yDir, maxcount
    add     hl, sp              ;; 
    ld      sp, hl              ;; 

.effect1_lp_init
    ld      (ix-1), 0 		;; x
    ld      (ix-2), 0		;; y
    ld      (ix-3), 1		;; xDir
    ld      (ix-4), 1		;; yDir
    ld      (ix-5), 0		;; maxcount_L
    ld      (ix-6), &C0		;; maxcount_H
.effect1_lp_cond
    inc     (ix-5)
    ld      a, (ix-5)
    cp      0
    jp      z, maxcount_L_end
    jp      effect1_lp_body
.maxcount_L_end
    inc     (ix-6)
    ld      a, (ix-6)
    cp      0
    jp      z, effect1_lp_end
.effect1_lp_body
    ;; if (x >= 79)
    ld      a, (ix-1)
    sub     79
    jp      c, not_cnd1
    ld      (ix-3), -1
.not_cnd1
    ;; if (x < 1)
    ld      a, (ix-1)
    sub     1
    jp      nc, not_cnd2
    ld      (ix-3), 1
.not_cnd2 
    ;; if (y >= 199)
    ld      a, (ix-2)
    sub     199
    jp      c, not_cnd3
    ld      (ix-4), -1
.not_cnd3
    ;; if (y < 1)
    ld      a, (ix-2)
    sub     1
    jp      nc, not_cnd4
    ld      (ix-4), 1
.not_cnd4

    ld      h, (ix-1)
    ld      l, (ix-2)
    call    getScreenAddress
    ld      (hl), 255
.effect1_lp_next
    ld      a, (ix-1)
    ld      b, (ix-3)
    add     b
    ld      (ix-1), a

    ld      a, (ix-2)
    ld      b, (ix-4)
    add     b
    ld      (ix-2), a

    jp      effect1_lp_cond
.effect1_lp_end

    ld      sp, ix
    pop     ix
    ret

.makeScreenAddrTable
    ld      b, 200
    ld      ix, makeScreenAddrTable_var_table
    ld      hl, &c000
.makeScreenAddrTable_lp
    ld      (ix+0), l
    ld      (ix+1), h
    inc     ix
    inc     ix

    call    scr_next_line
    djnz    makeScreenAddrTable_lp
    ret

.makeScreenAddrTable_var_table
defs 200 * 2

;; INPUT
;; H = x byte coordinate (0-79)
;; L = y coordinate (0-199)
;; OUTPUT
;; HL = screen address
.getScreenAddress
    ld      c, h
    ld      h, 0

    add     hl, hl

    ld      de, makeScreenAddrTable_var_table
    add     hl, de

    ld      a, (hl)
    inc     hl
    ld      h, (hl)
    ld      l, a

    ld      b, 0
    add     hl, bc

    ret

defs 1000
.stack
@javier-anton-ordonez
Copy link

man i'm crying i undertand nothing in my class of z80 assembly

@neuro-sys
Copy link
Author

@Javiton2005 Anything in particular that you don't understand?

@RheaProgramming
Copy link

@neuro-sys, do you know eZ80 assembly? I need some help with that

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment