;; test to exercise instructions which are not Z80-identical into greater depth
 
;; focus is mostly on IDA syntax variants, the goal is to have it thoroughly tested
 
    OPT --syntax=abf    ; but this is expected "default" mode of syntax for new sources
 
 
 
;; example macro to get "halt" which emits automatically halt+nop like rgbasm does
 
halt    MACRO
 
            @halt
 
            nop
 
        ENDM
 
    halt    ; = halt+nop
 
    @halt   ; = halt (only)
 
 
 
    ; "variables" crossing into the $FF00 area, so some of them can be accessed with LDH
 
        STRUCT struct1
 
a           BYTE    1
 
b           BYTE    2
 
        ENDS
 
 
 
        ORG     $FF00-4
 
varSX       struct1
 
var1        db      0x34
 
var2        dw      0x5678
 
var3        db      0xAB
 
var4        dw      0xCDEF
 
varS        struct1
 
 
 
        ORG     $8000
 
            ld      a,[var1]        ; like LD a,(a16) on Z80
 
            ld      a,[var3]
 
            ldh     a,[low var3]
 
            ldh     a,[var3]
 
            ldh     a,[var1]        ; should warn about truncating value (bug in source)
 
            ld      [var1],a        ; like LD (a16),a on Z80
 
            ld      [var3],a
 
            ldh     [low var3],a
 
            ldh     [var3],a
 
            ldh     [var1],a        ; should warn about truncating value (bug in source)
 
            ; repeat the same exercise, but with parentheses
 
            ld      a,(var1)
 
            ld      a,(var3)
 
            ldh     a,(low var3)
 
            ldh     a,(var3)
 
            ldh     a,(var1)
 
            ld      (var1),a
 
            ld      (var3),a
 
            ldh     (low var3),a
 
            ldh     (var3),a
 
            ldh     (var1),a
 
            ; the uselessly more explicit syntax (but should work)
 
            ld      a,[$ff00 + low var3]
 
            ld      [$ff00 + low var3],a
 
            ; these should warn, this is not correct way of writing it (bug in source)
 
            ld      a,[$ff00 + var3]
 
            ld      [$ff00 + var3],a
 
            ; accessing the structure members
 
            ldh     a,[varS.a]
 
            ldh     [varS.b],a
 
            ldh     a,[varSX.a]     ; warning, outside of $FFxx area
 
            ldh     [varSX.b],a     ; warning, outside of $FFxx area
 
            ld      a,[varS.a]      ; regular LD is optimized if possible
 
            ld      [varS.b],a      ; regular LD is optimized if possible
 
            ld      a,[varSX.a]
 
            ld      [varSX.b],a
 
 
 
            ; whitespace parsing in "(c)" operand (not much else to test)
 
            ld      a , ( c )
 
            ld      ( c ) , a
 
            ; illegal register combinations, all should produce some error (mostly "illegal instruction")
 
            ld      a , ( b )
 
            ld      ( b ) , a
 
            ld      b , ( c )       ; error, illegal instruction; --syntax=b reports "ld b,(mem)"
 
            ld      ( c ) , b
 
            ld      hl,(c)
 
            ld      (c),hl
 
 
 
            ld      a,(123)         ; check if low-memory warning is off in LR35902 mode (good idea?? not sure)
 
 
 
            ldi     a,(hl+)         ; error, mixed invalid syntax
 
            ldi     a , ( hl )
 
            ld      a , [ hl+ ]
 
            ld      a , [ hl + ]    ; error, the "hl+" must be together
 
            ld      a,(hl+0)        ; error, there's no such thing
 
 
 
            ldd     a,(hl-)         ; error, mixed invalid syntax
 
            ldd     a , ( hl )
 
            ld      a , [ hl- ]
 
            ld      a , [ hl - ]    ; error, the "hl-" must be together
 
            ld      a,(hl-0)        ; error, there's no such thing
 
 
 
            ldi     (hl+),a         ; error, mixed invalid syntax
 
            ldi     ( hl ) , a
 
            ld      [ hl+ ] , a
 
            ld      [ hl + ] , a    ; error, the "hl+" must be together
 
            ld      (hl+0),a        ; error, there's no such thing
 
 
 
            ldd     (hl-),a         ; error, mixed invalid syntax
 
            ldd     ( hl ) , a
 
            ld      [ hl- ] , a
 
            ld      [ hl - ] , a    ; error, the "hl-" must be together
 
            ld      (hl-0),a        ; error, there's no such thing
 
 
 
            ; wrong registers => errors
 
            ldi     a,(de)
 
            ldd     a,(de)
 
            ld      a,(de+)
 
            ld      a,(de-)
 
            ldi     l,(hl)
 
            ldd     l,(hl)
 
            ld      l,(hl+)
 
            ld      l,(hl-)
 
            ldi     (de),a
 
            ldd     (de),a
 
            ld      (de+),a
 
            ld      (de-),a
 
            ldi     (hl),l
 
            ldd     (hl),l
 
            ld      (hl+),l
 
            ld      (hl-),l
 
            ldi     (hl),1
 
            ldd     (hl),2
 
            ld      (hl+),3
 
            ld      (hl-),4
 
 
 
            ld      hl,sp               ; implicit +0
 
            ld      hl , sp + 0
 
            ld      hl , sp - 0
 
            ld      hl , sp + 1
 
            ld      hl , sp - 1
 
            ld      hl , sp + +1
 
            ld      hl , sp + -1
 
            ld      hl , sp + +1
 
            ld      hl , sp (+1)        ; error, there must be + or - right after "sp"
 
            ld      hl , sp + struct1   ; hl = sp + sizeof(struct1)
 
            ld      hl , sp + 127
 
            ld      hl , sp + 128       ; error, value is beyond range
 
            ld      hl , sp - 128
 
            ld      hl , sp - 129       ; error, value is beyond range
 
            ld      hl , de + 1         ; invalid
 
            ld      de , sp + 1         ; invalid
 
 
 
            ld      ( var2 + 4 ) , sp
 
            ld      ( var2 + 4 ) , hl   ; invalid
 
 
 
            ; illegal "add sp,r8" variants
 
            add     sp
 
            add     sp ,
 
            add     sp , hl
 
            add     sp , +128
 
            add     sp , -129
 
            ; legit "add sp,r8"
 
            add     sp , 0
 
            add     sp , +127
 
            add     sp , -128
 
            add     sp , struct1        ; sp += sizeof(struct1)
 
 
 
            ; some more malformed lines (intermezzo ... getting back to opcodes already above)
 
            ld      (hl+)
 
            ld      [hl+]
 
            ld      (hl+),
 
            ld      [hl+],
 
            ld      [hl+),a
 
            ld      (hl+],a
 
            ldi     (hl)
 
            ldi     [hl]
 
            ldd     (hl)
 
            ldd     [hl]
 
            ldi     (hl),
 
            ldi     [hl],
 
            ldd     (hl),
 
            ldd     [hl],
 
            ldh     a
 
            ldh     a,
 
            ldh     (var3)
 
            ldh     (var3),
 
            ldh     [var3]
 
            ldh     [var3],
 
            ldh     [var3),a
 
            ldh     (var3],a
 
            ld      hl,s
 
 
 
            ; illegal syntax of swap
 
            swap
 
            swap    (var3)
 
            swap    var3
 
            swap    de
 
            swap    [de]
 
            swap    (a)
 
            swap    a,b
 
            ; legit ones
 
            swap    a
 
            swap    a,,b        ; multi-arg
 
 
 
            ; illegal syntax of stop
 
            stop    a
 
            stop    [0]
 
            stop    (hl)
 
            stop    0,,1        ; no multi-arg for STOP implemented
 
            ; legit ones
 
            stop                ; implicit 0
 
            stop    0
 
            stop    0xE0
 
 
 
            ; more multi-args exercised (only in "--syntax=a" mode)
 
            ldi     a,[hl],,a,(hl),,[hl],a,,(hl),a
 
            ldd     a,[hl],,a,(hl),,[hl],a,,(hl),a
 
            ld      a,[hl+],,a,(hl+),,[hl+],a,,(hl+),a
 
            ld      a,[hl-],,a,(hl-),,[hl-],a,,(hl-),a
 
            ldh     a,[varS.a],,[varS.b],a,,a,(varS.a),,(varS.b),a
 
            add     sp,3,,sp,4
 
            ld      hl,sp,,hl,sp+5,,hl,sp+6
 
 
 
            ;;;; more extra tests after pushing the commit (as always)
 
 
 
            ; LDH automagic in LD - range checks
 
            ld      a,(0xFEFF+0)        ; outside
 
            ld      a,(0xFEFF+1)        ; LDH
 
            ld      a,(0xFEFF+256)      ; LDH
 
            ld      a,(0xFEFF+257)      ; outside + warning
 
            ld      (0xFEFF+0),a        ; outside
 
            ld      (0xFEFF+1),a        ; LDH
 
            ld      (0xFEFF+256),a      ; LDH
 
            ld      (0xFEFF+257),a      ; outside + warning
 
 
 
    END     ; scratcharea