Skip to content

Instantly share code, notes, and snippets.

@DonaldHays
Created February 21, 2019 02:50
Show Gist options
  • Save DonaldHays/a2cdddba571a20d73e9b5f6550695cf3 to your computer and use it in GitHub Desktop.
Save DonaldHays/a2cdddba571a20d73e9b5f6550695cf3 to your computer and use it in GitHub Desktop.
Branching pseudo-instructions
if !def(utilities_branching_inc)
utilities_branching_inc set 1
; ==============================================================================
; branch.inc
;
; Macros for branching pseudo-instructions that are easier to understand at a
; glance.
;
; These macros are intended to be used after a cp, sub, or equivalent operation.
; ==============================================================================
; ===
; JR
; While jr ultimately compiles down to numeric offsets, and these macros will
; thus compile if you pass a number, it's recommended that you only pass labels,
; because these macros don't all expand out to the same length, so let the
; assembler take care of computing the offsets.
; ===
; - macro jrlt label
; Relative jumps to `label` if the previous operation resulted in a
; "less than" condition.
jrlt: macro
jr c, \1
endm
; - macro jrlte label
; Relative jumps to `label` if the previous operation resulted in a
; "less than or equal to" condition.
jrlte: macro
jr c, \1
jr z, \1
endm
; - macro jrgt label
; Relative jumps to `label` if the previous operation resulted in a
; "greater than" condition.
jrgt: macro
jr c, .endCompare@
jr nz, \1
.endCompare\@
endm
; - macro jrgte label
; Relative jumps to `label` if the previous operation resulted in a
; "greater than or equal to" condition.
jrgte: macro
jr nc, \1
endm
; - macro jreq label
; Relative jumps to `label` if the previous operation resulted in an
; "equal to" condition.
jreq: macro
jr z, \1
endm
; - macro jrne label
; Relative jumps to `label` if the previous operation resulted in a
; "not equal" condition.
jrne: macro
jr nz, \1
endm
; ===
; JP
; ===
; - macro jplt label
; Jumps to `label` if the previous operation resulted in a "less than"
; condition.
jplt: macro
jp c, \1
endm
; - macro jplte label
; Jumps to `label` if the previous operation resulted in a "less than or equal
; to" condition.
jplte: macro
jp c, \1
jp z, \1
endm
; - macro jpgt label
; Jumps to `label` if the previous operation resulted in a "greater than"
; condition.
jpgt: macro
jr c, .endCompare@
jp nz, \1
.endCompare\@
endm
; - macro jpgte label
; Jumps to `label` if the previous operation resulted in a "greater than or
; equal to" condition.
jpgte: macro
jp nc, \1
endm
; - macro jpeq label
; Jumps to `label` if the previous operation resulted in an "equal to"
; condition.
jpeq: macro
jp z, \1
endm
; - macro jpne label
; Jumps to `label` if the previous operation resulted in a "not equal"
; condition.
jpne: macro
jp nz, \1
endm
; ===
; CALL
; ===
; - macro calllt label
; Calls `label` if the previous operation resulted in a "less than" condition.
calllt: macro
call c, \1
endm
; - macro calllte label
; Calls `label` if the previous operation resulted in a "less than or equal to"
; condition.
calllte: macro
call c, \1
call z, \1
endm
; - macro callgt label
; Calls `label` if the previous operation resulted in a "greater than"
; condition.
callgt: macro
jr c, .endCompare@
call nz, \1
.endCompare\@
endm
; - macro callgte label
; Calls `label` if the previous operation resulted in a "greater than or equal
; to" condition.
callgte: macro
call nc, \1
endm
; - macro calleq label
; Calls `label` if the previous operation resulted in an "equal to" condition.
calleq: macro
call z, \1
endm
; - macro callne label
; Calls `label` if the previous operation resulted in a "not equal" condition.
callne: macro
call nz, \1
endm
; ===
; RET
; ===
; - macro retlt label
; Returns if the previous operation resulted in a "less than" condition.
retlt: macro
ret c, \1
endm
; - macro retlte label
; Returns if the previous operation resulted in a "less than or equal to"
; condition.
retlte: macro
ret c, \1
ret z, \1
endm
; - macro retgt label
; Returns if the previous operation resulted in a "greater than" condition.
retgt: macro
jr c, .endCompare@
ret nz, \1
.endCompare\@
endm
; - macro retgte label
; Returns if the previous operation resulted in a "greater than or equal to"
; condition.
retgte: macro
ret nc, \1
endm
; - macro reteq label
; Returns if the previous operation resulted in an "equal to" condition.
reteq: macro
ret z, \1
endm
; - macro retne label
; Returns if the previous operation resulted in a "not equal" condition.
retne: macro
ret nz, \1
endm
endc
@joeldipops
Copy link

joeldipops commented May 25, 2019

While jr ultimately compiles down to numeric offsets, and these macros will
thus compile if you pass a number, it's recommended that you only pass labels,
because these macros don't all expand out to the same length, so let the
assembler take care of computing the offsets.

This is how I've thought of tackling that problem.

LBL_CHARS EQUS "\"_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\""
jrlte: macro
    jr C, \1

    ; If \1 starts like a constant/label, not a number
    IF (STRIN(LBL_CHARS, STRSUB("\1", 1, 1)) != 0)
        jr Z, \1
    ELSE
        jr Z, \1 - 2 ; -2 since jr is two bytes.
    ENDC
endm

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