; Desktop/x/build/test.asm · NASM intel · .asm only · no gas · no AT&T
; language iron: bgf · spv · rtx · raw iron
; freestanding linux x86_64

bits 64
default rel

W       equ 64
H       equ 64
SEED    equ 0xC0FFEE
RAD     equ 16

section .text
global _start

; bgf · edi=a esi=b → eax=(a-b)|1
bgf:
        mov     eax, edi
        sub     eax, esi
        or      eax, 1
        ret

; spv · edi=a esi=b edx=c → eax=(a^b^c)|1
spv:
        mov     eax, edi
        xor     eax, esi
        xor     eax, edx
        or      eax, 1
        ret

; rtx · edi=a esi=b edx=c → eax=field · r8d=free
rtx:
        mov     r8d, edi
        xor     r8d, esi
        xor     r8d, edx
        or      r8d, 1
        mov     eax, edi
        sub     eax, esi
        or      eax, 1
        ret

; abs32 · edi → eax
abs32:
        mov     eax, edi
        cdq
        xor     eax, edx
        sub     eax, edx
        ret

_start:
        xor     r12d, r12d              ; misses
        xor     r14d, r14d              ; y
.y:
        cmp     r14d, H
        jge     .fin
        xor     r15d, r15d              ; x
.x:
        cmp     r15d, W
        jge     .ny

        ; cheb = max(|x-W/2|, |y-H/2|)
        mov     edi, r15d
        sub     edi, W/2
        call    abs32
        mov     r9d, eax
        mov     edi, r14d
        sub     edi, H/2
        call    abs32
        cmp     r9d, eax
        jge     .ch
        mov     r9d, eax
.ch:
        ; field_want = bgf(cheb, RAD)
        mov     edi, r9d
        mov     esi, RAD
        call    bgf
        mov     r10d, eax

        ; free_xy = spv(x,y,SEED) · separate lane
        mov     edi, r15d
        mov     esi, r14d
        mov     edx, SEED
        call    spv
        mov     r11d, eax

        ; rtx(cheb, RAD, SEED)
        mov     edi, r9d
        mov     esi, RAD
        mov     edx, SEED
        call    rtx
        cmp     eax, r10d
        je      .fok
        inc     r12d
.fok:
        ; r8 free must equal spv(cheb,RAD,SEED)
        push    r8                      ; save free from rtx
        mov     edi, r9d
        mov     esi, RAD
        mov     edx, SEED
        call    spv
        pop     r8
        cmp     r8d, eax
        je      .sok
        inc     r12d
.sok:
        ; both lanes odd (live resolve live)
        test    r10d, 1
        jnz     .o1
        inc     r12d
.o1:
        test    r11d, 1
        jnz     .o2
        inc     r12d
.o2:
        inc     r15d
        jmp     .x
.ny:
        inc     r14d
        jmp     .y

.fin:
        test    r12d, r12d
        jnz     .bad

        mov     rax, 1
        mov     rdi, 1
        lea     rsi, [msg_ok]
        mov     rdx, msg_ok_len
        syscall
        mov     rax, 60
        xor     rdi, rdi
        syscall

.bad:
        mov     rax, 1
        mov     rdi, 1
        lea     rsi, [msg_bad]
        mov     rdx, msg_bad_len
        syscall
        mov     rax, 60
        mov     rdi, 2
        syscall

section .rodata
msg_ok:
        db "test OK · NASM .asm · bgf+spv+rtx · raw iron", 10
msg_ok_len equ $ - msg_ok
msg_bad:
        db "test FAIL · iron miss", 10
msg_bad_len equ $ - msg_bad
