Skip to content

some old code

Alex edited this page Aug 15, 2026 · 2 revisions
Raycast.asm:
; USING SIMPLIFIED SYNTAX, ONLY PSEUDO-ASSEMBLY.
; SOMETIMES THE EAM.SET IS IMPLICIT.
; THERE'S A LOT OF BANK SWITCHING AND I CAN'T BE ARSED TO MAKE THEM ALL EXPLICIT.
;
; THIS IS THE ROUTINE I WILL GET A SIZE ESTIMATE ON:


; mapX = static_cast<int>(posX);

LDM R0 M$[PosXHi]
LDM R1 M$[PosXLo]
STM R0 M$[Arg0]
STM R1 M$[Arg1]
CAL CAST(f32, i32)

LDM R0 M$[CastReturnHI]
LDM R1 M$[CastReturnLO]
STM R0 M$[mapXHi]
STM R1 M$[mapXLo]


; mapY = static_cast<int>(posY);

LDM R0 M$[posYHi]
LDM R1 M$[posYLo]
STM R0 M$[Arg0]
STM R1 M$[Arg1]
CAL CAST(f32,i32)

LDM R0 M$[CastReturnHi]
LDM R1 M$[CastReturnLo]
STM R0 M$[MapYHi]
STM R1 M$[MapYLo]


; if(rayDirX == 0)
; {
;     deltaX = infinity;
; }
; else
; {
;     deltaX = abs(1/rayDirX);
; }

LDM R0 M$[rayDirXLo]
LDM R1 M$[rayDirXHi]
OR R0 R0 R1
AND R0 R0 0x7FFF
STJ NZA
JNE R0 0x0000

STM 0x7F80 M$[deltaXLo]
STM 0x0000 M$[deltaXHi]
STJ cont0
JMP


NZA:

LDM R0 M$[rayDirXLo]

EAM.SET 0x07FF

STM R0 M$[FP32.B_LOW]
STM R1 M$[FP32.B_HIGH]
STM 0x3F80 M$[FP32.A_HIGH]
STM 0x0000 M$[FP32.A_LOW]
STM CMD_DIVIDE M$[FP32_CMD]

LDM R0 M$[FP32_outLOW]
LDM R1 M$[FP32_outHIGH]

STM R0 M$[deltaXLo]
STM R1 M$[deltaXHigh]

LDM R0 M$[deltaXlow]
LDM R1 M$[deltaXHigh]

STM R0 M$[Arg0]
STM R1 M$[Arg1]

CAL absFP32

LDM R0 M$[Ret0]
LDM R1 M$[Ret1]

STM R0 M$[deltaXLow]
STM R1 M$[deltaXHi]


cont0:

EAM.SET 0x0000


; if(rayDirY == 0)
; {
;     deltaY = infinity;
; }
; else
; {
;     deltaY = abs(1/rayDirY);
; }

LDM R0 M$[rayDirYLo]
LDM R1 M$[rayDirYHi]
OR R0 R0 R1
AND R0 R0 0x7FFF
STJ NZB
JNE R0 0x0000

STM 0x7F80 M$[deltaYLo]
STM 0x0000 M$[deltaYHi]
STJ cont1
JMP


NZB:

LDM R0 M$[rayDirYLo]

EAM.SET 0x07FF

STM R0 M$[FP32.B_LOW]
STM R1 M$[FP32.B_HIGH]
STM 0x3F80 M$[FP32.A_HIGH]
STM 0x0000 M$[FP32.A_LOW]
STM CMD_DIVIDE M$[FP32_CMD]

LDM R0 M$[FP32_outLOW]
LDM R1 M$[FP32_outHIGH]

STM R0 M$[deltaYLo]
STM R1 M$[deltaYHigh]

STM R0 M$[Arg0]
STM R1 M$[Arg1]

CAL absFP32

LDM R0 M$[Ret0]
LDM R1 M$[Ret1]

; NOTE: Original source says deltaX here.
STM R0 M$[deltaXLow]
STM R1 M$[deltaXHi]


cont1:

EAM.SET 0x0000


; if(rayDirX < 0)
; {
;     stepX = -1;
;     sideDistX = (posX - mapX) * deltaX;
; }
; else
; {
;     stepX = 1;
;     sideDistX = (mapX + (1 - posX)) * deltaX;
; }

LDM R0 M$[rayDirXHI]
LDM R1 M$[rayDirXLO]
AND R0 R0 0x8000

STM R0 M$[Buffer0]
STM R1 M$[Buffer1]

STJ NX
JNE R0 0x0000

; FIXME: Original formatting/source had:
; STM $FFFF
; M$[StepXlo]

STM $FFFF M$[StepXlo]
STM $FFFF M$[StepXHi]

STJ cont2
JMP


NX:

LDM R0 M$[posXLo]
LDM R1 M$[posXHi]

STM R0 M$[FP32_BLOW]
STM R1 M$[FP32_BHIGH]
STM 0x3F80 M$[FP32_AHIGH]
STM 0x0000 M$[FP32_ALOW]
STM CMD_SUB M$[FP32_CMD]

LDM R0 M$[FP32_OUTLOW]
LDM R1 M$[FP32_OUTHIGH]

LDM R2 M$[MapXHi]
LDM R3 M$[MapXLo]

STM R2 M$[PosXLo]
STM R3 M$[PosXHi]
STM R0 M$[MapXLo]
STM R1 M$[MapXHi]

LDM R0 M$[posXLo]
LDM R1 M$[posXHi]

STM 0x0000 M$[stepXLo]
STM 0x0001 M$[stepXHi]

LDM R0 M$[Buffer0]
LDM R1 M$[Buffer1]


cont2:

STM R0 M$[FP32_ALOW]
STM R1 M$[FP32_AHIGH]

LDM R0 M$[MapXlow]
LDM R1 M$[MapXHigh]

STM R0 M$[FP32_BLOW]
STM R1 M$[FP32_BHIGH]
STM CMD_SUB M$[FP32_CMD]

LDM R0 M$[FP32_OUTLOW]
LDM R1 M$[FP32_OUTHIGH]

; FIXME: Original had M${FP32_AHIGH]
STM R0 M$[FP32_ALOW]
STM R1 M$[FP32_AHIGH]

LDM R0 M$[deltaXLo]
LDM R1 M$[deltaXHi]

STM R0 M$[FP32_BLOW]
STM R1 M$[FP32_BHIGH]

; FIXME: Original contained a stray "STM" before CMD_MUL.
STM CMD_MUL M$[FP32_CMD]

LDM R0 M$[FP32_OUTLOW]
LDM R1 M$[FP32_OUTHIGH]

STM R0 M$[sideDistXLo]
STM R1 M$[sideDistXHi]


; if(rayDirY < 0)
; {
;     stepY = -1;
;     sideDistY = (posY - mapY) * deltaY);
; }
; else
; {
;     stepY = 1;
;     sideDistY = (mapY +1 - posY ) * deltaY);
; }

LDM R0 M$[rayDirYHI]
LDM R1 M$[rayDirYLO]
AND R0 R0 0x8000

STM R0 M$[Buffer0]
STM R1 M$[Buffer1]

STJ NY
JNE R0 0x0000

STM $FFFF M$[StepYlo]
STM $FFFF M$[StepYHi]

STJ cont3
JMP


NY:

LDM R0 M$[posYLo]
LDM R1 M$[posYHi]

STM R0 M$[FP32_BLOW]
STM R1 M$[FP32_BHIGH]
STM 0x3F80 M$[FP32_AHIGH]
STM 0x0000 M$[FP32_ALOW]
STM CMD_SUB M$[FP32_CMD]

LDM R0 M$[FP32_OUTLOW]
LDM R1 M$[FP32_OUTHIGH]

LDM R2 M$[MapYHi]
LDM R3 M$[MapYLo]

STM R2 M$[PosYLo]
STM R3 M$[PosYHi]
STM R0 M$[MapYLo]
STM R1 M$[MapYHi]

LDM R0 M$[posYLo]
LDM R1 M$[posYHi]

STM 0x0000 M$[stepYLo]
STM 0x0001 M$[stepYHi]

LDM R0 M$[Buffer0]
LDM R1 M$[Buffer1]


cont3:

STM R0 M$[FP32_ALOW]
STM R1 M$[FP32_AHIGH]

LDM R0 M$[MapYlow]
LDM R1 M$[MapYHigh]

STM R0 M$[FP32_BLOW]
STM R1 M$[FP32_BHIGH]
STM CMD_SUB M$[FP32_CMD]

LDM R0 M$[FP32_OUTLOW]
LDM R1 M$[FP32_OUTHIGH]

STM R0 M$[FP32_ALOW]
STM R1 M$[FP32_AHIGH]

LDM R0 M$[deltaYLo]
LDM R1 M$[deltaYHi]

STM R0 M$[FP32_BLOW]
STM R1 M$[FP32_BHIGH]
STM CMD_MUL M$[FP32_CMD]

LDM R0 M$[FP32_OUTLOW]
LDM R1 M$[FP32_OUTHIGH]

STM R0 M$[sideDistYLo]
STM R1 M$[sideDistYHi]


; hit = false;

STM 0x0000 M$[hit]


; while(!hit)
; {
;     if(sideDistX < sideDistY)
;     {
;         sideDistX += deltaX;
;         mapX += stepX;
;         side = 0;
;     }
;     else
;     {
;         sideDistY += deltaY;
;         mapY += stepY;
;         side = 1;
;     }
;
;     if(map.getTile(mapX,mapY).isCollidable)
;     {
;         hit = true;
;     }
; }


cont4:

STJ whileExit

LDM R0 M$[hit]
JEQ R0 0x0001

LDM R0 M$[sideXDistLo]
LDM R1 M$[sideXDistHi]

STM R0 M$[FP32_ALOW]
STM R1 M$[FP32_AHIGH]

LDM R0 M$[sideYDistLo]
LDM R1 M$[sideYDistHi]

STM R0 M$[FP32_BLOW]
STM R1 M$[FP32_BHIGH]
STM CMD_SUB M$[FP32_CMD]

LDM R0 M$[FP32_OUTHIGH]

STJ doY
JLT R0 0x0000


; sideDistX += deltaX

LDM R0 M$[deltaXlo]
LDM R1 M$[deltaXHi]

STM R0 M$[Arg0]
STM R1 M$[Arg1]

LDM R0 M$[sideDistXLo]
LDM R1 M$[sideDistXHi]

STM R0 M$[Arg2]
STM R1 M$[Arg3]

CAL AddF32

EAM.SET 0x07FF

LDM R0 M$[FP32_OUTLOW]
LDM R1 M$[FP32_OUTHIGH]

EAM.SET 0x07FF

STM R0 M$[sideDistXlo]
STM R1 M$[sideDistXHi]


; mapX += stepX

LDM R0 M$[MapXLO]
LDM R1 M$[MapXHI]

STM R0 M$[Arg0]
STM R1 M$[Arg1]

LDM R0 M$[stepXLo]

; FIXME: Original had LDM R0 here.
LDM R0 M$[stepXHi]

STM R0 M$[Arg2]
STM R1 M$[Arg3]

CAL AddI32

EAM.SET 0x07FF

LDM R0 M$[int32_Outlo]
LDM R1 M$[int32_OutHi]

EAM.SET 0x0000

STM R0 M$[mapXlo]
STM R1 M$[mapXhi]

STM 0x0000 M$[sideLo]
STM 0x0000 M$[sideHi]

STJ cont5
JMP


doY:


; sideDistY += deltaY

LDM R0 M$[deltaYlo]
LDM R1 M$[deltaYHi]

STM R0 M$[Arg0]
STM R1 M$[Arg1]

LDM R0 M$[sideDistYLo]
LDM R1 M$[sideDistYHi]

STM R0 M$[Arg2]
STM R1 M$[Arg3]

CAL AddF32

; FIXME: Original says 0x07FFF.
EAM.SET 0x07FFF

LDM R0 M$[FP32_OUTLOW]
LDM R1 M$[FP32_OUTHIGH]

EAM.SET 0x0000

STM R0 M$[sideDistYlo]
STM R1 M$[sideDistYHi]


; mapY += stepY

LDM R0 M$[MapYLO]
LDM R1 M$[MapYHI]

STM R0 M$[Arg0]
STM R1 M$[Arg1]

LDM R0 M$[stepYLo]

; FIXME: Original had LDM R0 here.
LDM R0 M$[stepYHi]

STM R0 M$[Arg2]
STM R1 M$[Arg3]

CAL AddI32

EAM.SET 0x07FF

LDM R0 M$[int32_Outlo]
LDM R1 M$[int32_OutHi]

STM R0 M$[mapYlo]
STM R1 M$[mapYhi]

STM 0x0000 M$[sideLo]
STM 0x0001 M$[sideHi]


cont5:

LDM R0 M$[mapXlo]
LDM R1 M$[mapXhi]
LDM R2 M$[mapYlo]
LDM R3 M$[mapYhi]

STM R0 M$[Arg0]
STM R1 M$[Arg1]
STM R2 M$[Arg2]
STM R3 M$[Arg3]

CAL map.getTile.getCollidable

LDM R0 M$[Ret0]

STJ NotHit
JNE R0 0x0001

STM 0x0001 M$[hit]


NotHit:

STJ cont4
JMP


whileExit:


; if(side == 0)
; {
;     pwalldist =
;         (mapX - posX + (1 - stepX) / 2) / rayDirX;
; }
; else
; {
;     pwallDist =
;         (mapY - posY +( 1 - stepY) / 2) / rayDirY;
; }

LDM R0 M$[sideLo]

STJ sideNZ
JNE R0 0x0000


; X-side wall

LDM R0 M$[mapXLo]
LDM R1 M$[mapXHi]

STM R0 M$[Arg0]
STM R1 M$[Arg1]

LDM R0 M$[posXLo]
LDM R1 M$[posXHi]

STM R0 M$[Arg2]
STM R1 M$[Arg3]

CAL CAST(I32, F32)
CAL SubF32

LDM R0 M$[Ret0]
LDM R1 M$[Ret1]

STM R0 M$[Buffer0]
STM R1 M$[Buffer1]

LDM R0 M$[stepXlo]
LDM R1 M$[stepXhi]

STM R0 M$[Arg2]
STM R1 M$[Arg3]

STM 0x3F80 M$[Arg0]
STM 0x0000 M$[Arg1]

CAL CAST(i32, f32,arg2,arg3)
CAL SubF32

LDM R0 M$[Buffer0]
LDM R1 M$[Buffer1]

LDM R2 M$[Ret0]
LDM R3 M$[Ret1]

STM R0 M$[Arg0]
STM R1 M$[Arg1]
STM R2 M$[Arg2]
STM R3 M$[Arg3]

CAL AddF32

LDM R0 M$[Ret0]
LDM R1 M$[Ret1]

STM R0 M$[Arg0]
STM R1 M$[Arg1]

STM 0x4000 M$[Arg2]
STM 0x0000 M$[Arg3]

CAL DivF32

LDM R0 M$[Ret0]
LDM R1 M$[Ret1]

STM R0 M$[Arg0]

; FIXME: Original says STM R0 M$[Arg1].
STM R0 M$[Arg1]

LDM R0 M$[rayDirXlo]
LDM R1 M$[rayDirXhi]

STM R0 M$[Arg2]
STM R1 M$[Arg3]

CAL DivF32

LDM R0 M$[Ret0]
LDM R1 M$[Ret1]

STJ cont6
JMP


sideNZ:


; Y-side wall

LDM R0 M$[mapYLo]
LDM R1 M$[mapYHi]

STM R0 M$[Arg0]
STM R1 M$[Arg1]

LDM R0 M$[posYLo]
LDM R1 M$[posYHi]

STM R0 M$[Arg2]
STM R1 M$[Arg3]

CAL CAST(I32, F32)
CAL SubF32

LDM R0 M$[Ret0]
LDM R1 M$[Ret1]

STM R0 M$[Buffer0]
STM R1 M$[Buffer1]

LDM R0 M$[stepYlo]
LDM R1 M$[stepYhi]

STM R0 M$[Arg2]
STM R1 M$[Arg3]

STM 0x3F80 M$[Arg0]
STM 0x0000 M$[Arg1]

CAL CAST(i32, f32,arg2,arg3)
CAL SubF32

LDM R0 M$[Buffer0]
LDM R1 M$[Buffer1]

LDM R2 M$[Ret0]
LDM R3 M$[Ret1]

STM R0 M$[Arg0]
STM R1 M$[Arg1]
STM R2 M$[Arg2]
STM R3 M$[Arg3]

CAL AddF32

LDM R0 M$[Ret0]
LDM R1 M$[Ret1]

STM R0 M$[Arg0]
STM R1 M$[Arg1]

STM 0x4000 M$[Arg2]
STM 0x0000 M$[Arg3]

CAL DivF32

LDM R0 M$[Ret0]
LDM R1 M$[Ret1]

STM R0 M$[Arg0]

; FIXME: Original says STM R0 M$[Arg1].
STM R0 M$[Arg1]

LDM R0 M$[rayDirYlo]
LDM R1 M$[rayDirYhi]

STM R0 M$[Arg2]
STM R1 M$[Arg3]

CAL DivF32

LDM R0 M$[Ret0]
LDM R1 M$[Ret1]


cont6:

STM R0 M$[PWalldistLo]
STM R1 M$[PWallDistHi]


; lineHeight = screenHeight / pwallDist;

LDM R0 M$[screenHeightLo]
LDM R1 M$[screemHeightHi]

LDM R2 M$[pwallDistLo]
LDM R3 M$[pwallDistHi]

STM R0 M$[Arg0]
STM R1 M$[Arg1]
STM R2 M$[Arg2]
STM R3 M$[Arg3]

CAL DivF32

LDM R0 M$[Ret0]
LDM R1 M$[Ret1]

STM R0 M$[Arg0]
STM R1 M$[Arg1]

CAL CAST(f32, i32)

LDM R0 M$[Ret0]
LDM R1 M$[Ret1]

STM R0 M$[screenHeightLo]
STM R1 M$[screenHeightHi]


A*.asm:
; =====================================================================
; A4G::PATHFIND COMPLETE SUBROUTINE (Custom 16-bit RISC-CISC Hybrid ISA)
;
; Register Allocation Map:
;   R0 = Primary Iterator Pointer (scanning open/neighbor arrays)
;   R1 = Loop Boundary Limit Pointer (upper tracking bound)
;   R2 = Segmented Memory Page Bank Tracker (EAM)
;   R3 = Current / Winning Node Address Pointer (currentNode)
;   R4 = General Scratch Register A
;   R5 = General Scratch Register B
;   R6 = Internal Context Tracker
;   R7 = Stack Pointer (SP) / Subroutine Return Management
; =====================================================================

; --- 1. INITIALISATION & EARLY EXITS ---
LDM R4 M$[Start]
LDM R5 M$[End]
LDM R2 M$[Mode]

STJ .earlyExit
JEQ R4 0x0000                        ; Early exit if Start == NULL
JEQ R5 0x0000                        ; Early exit if End == NULL
JEQ R4 R5                            ; Early exit if Start == End

; Protect root parameters in fast memory buffers
STM R4 M$[Buffer0]
STM R5 M$[Buffer1]
STM R2 M$[Buffer2]

; Trigger Hardware-Accelerated Memclr via DMA / Subroutine
LDM R0 M$[*open_low]
LDM R2 M$[*open_high]
STM R0 M$[Arg0]
STM R2 M$[Arg1]
STM 0x0200 M$[Arg2]                  ; Footprint block allocation length
CAL memclr

LDM R0 M$[*closed_low]
LDM R2 M$[*closed_high]
STM R0 M$[Arg0]
STM R2 M$[Arg1]
CAL memclr

; Restore primary parameters from buffer slots
LDM R4 M$[Buffer0]
LDM R5 M$[Buffer1]
LDM R2 M$[Buffer2]

; Set start->gScore = 0
STM 0x0000 M$[g_low]
STM 0x0000 M$[g_high]

; Calculate start->hScore = Heuristic(start, end)
STM R4 M$[Arg0]
STM R5 M$[Arg1] 
CAL calc_heuristic
LDM R0 M$[Ret0]
LDM R2 M$[Ret1]
STM R0 M$[hScore_low]
STM R2 M$[hScore_high]

; Calculate start->fScore = gScore + hScore (Route to 32-bit FPU Coprocessor)
LDM R0 M$[gScore_low]
LDM R2 M$[gScore_high]
STM R0 M$[Arg0]
STM R2 M$[Arg1]
LDM R0 M$[hScore_low]
LDM R2 M$[hScore_high]
STM R0 M$[Arg2]
STM R2 M$[Arg3]
CAL FP_ADD                           
LDM R0 M$[Ret0] 
LDM R2 M$[Ret1]

; Push start node pointer onto open list array
LDM R0 M$[open_low]
LDM R2 M$[open_high]
EAM.SET R2 
LDM R5 M$[open_size]
ADD R5 R5 0x0001
ADD R6 R5 R0
STM R4 M$[R6]
XOR R6 R6 R6
XOR R5 R5 R5

; =====================================================================
; 2. MAIN EXECUTION STATE (while open.size > 0)
; =====================================================================
big_while:
    STJ.C .build_path
    LDM R4 M$[open_size]
    JLE R4 0x0000                    ; Implicit compare: exit loop if size <= 0

    ; Reset Minimum Scan: Best Score = Positive Infinity (0x7F800000)
    STM 0x7F80 M$[Arg0]
    STM 0x0000 M$[Arg1]
    XOR R3 R3 R3                     ; Clear active currentNode tracker

    LDM R0 M$[open_low]
    LDM R4 M$[open_size_times_two]   
    ADD R1 R0 R4                     ; R1 = Upper Boundary Limit (open_low + size*2)
    LDM R2 M$[open_high]             ; Keep open bank page loaded in R2

; --- LINEAR BEST-SCORE SCAN (O(1) Priority Extraction) ---
loop:
    EAM.SET R2                       ; Set page bank context for open array traversal
    STJ.C .loopExit                  ; Pre-load loop exit destination target
    JGE R0 R1                        ; Natively compare R0 >= R1. Branch if finished scanning.
    EAM.SET 0x0000                   ; Restore base memory page

    ; Fetch target node address fields
    LDM R4 M$[R0++]                  ; R4 = target_node_low
    LDM R5 M$[R0++]                  ; R5 = target_node_high
    EAM.SET R5                       ; Flip EAM page to read target node properties
    
    ; Route node scores directly to Floating-Point Coprocessor via memory registers
    ADD R4 R4 M$[f_score_low_offset] 
    LDM R5 M$[R4++]                  
    STM R5 M$[Arg2]
    LDM R5 M$[R4]                    
    STM R5 M$[Arg3]
    
    CAL FP_SUBTRACT                  ; Evaluate score differences
    LDM R4 M$[Ret1]                  
    
    ; Re-verify open list page layout alignment before looping
    LDM R5 M$[open_high]
    EAM.SET R5

    STJ loop
    JGT R4 0x0000                    ; If Ret1 > 0, existing score remains lowest. Skip.
    
    ; --- UPDATE SCAN TRACKER ---
    LDM R4 M$[Ret0]
    STM R4 M$[Arg0]                  ; Update best score low boundary
    LDM R4 M$[Ret1]
    STM R4 M$[Arg1]                  ; Update best score high boundary
    
    ; Deduce the precise memory coordinate layout of this winning pointer
    SUB R4 R0 0x0002
    LDM R3 M$[R4]                    ; R3 safely hoards the winning node memory address (currentNode)

    STJ loop
    JMP                              ; Advance scan iteration natively

; =====================================================================
; 3. NODE DELETION & NEIGHBOR EXPANSION
; =====================================================================
.loopExit:
    ; Erase chosen node (R3) from Open list via O(1) index swap trick
    CAL erase(open.begin)            

    ; Add current node (R3) to the Closed list buffer
    LDM R0 M$[closed_low]
    LDM R2 M$[closed_high]
    EAM.SET R2 
    LDM R4 M$[closed_size] 
    ADD R4 R4 R0
    STM R3 M$[R4++]
    STM R6 M$[R4]                    ; Element is now marked permanently CLOSED

    ; Check if currentNode == end
    LDM R4 M$[Buffer1]               ; Load End node address pointer
    STJ .build_path
    JEQ R3 R4                        ; If currentNode == end, jump to path builder

    ; --- SETUP NEIGHBOR EVALUATION ARRAY ---
    ; Route current node connections through the 16-bit register configurations
    ADD R4 R3 M$[connections_offset]
    LDM R0 M$[R4++]                  ; R0 = neighbor array pointer low
    LDM R2 M$[R4]                    ; R2 = neighbor array pointer high
    
    LDM R4 M$[max_connections_bytes]
    ADD R1 R4 R0                     ; R1 = neighbor looping upper boundary limits

.neighbor_loop:
    STJ .neighbors_done
    JGE R0 R1                        ; Natively drop out if all connected targets evaluated
    
    EAM.SET R2
    LDM R4 M$[R0++]                  ; R4 = individual neighbor address low (c.target)
    LDM R5 M$[R0++]                  ; R5 = individual neighbor address high
    
    STJ .next_neighbor
    JEQ R4 0x0000                    ; Ignore empty nodes or perimeter walls ('0')

    ; Constant time lookup: query node status byte to skip if CLOSED (0x0200)
    EAM.SET R5
    ADD R6 R4 M$[status_offset]
    LDM R6 M$[R6]
    STJ .next_neighbor
    JEQ R6 0x0200                    ; Skip if neighbor is closed

    ; =====================================================================
    ; 4. FLOATING-POINT COPOCESSOR SCORING MATRIX
    ; =====================================================================
    ; Save loop pointers to scratch memory blocks to protect them during calculation
    STM R0 M$[Temp_Neighbor_Ptr]
    STM R2 M$[Temp_Neighbor_Bank]
    STM R4 M$[Active_Target_Low]
    STM R5 M$[Active_Target_High]

    ; --- Step A: Gscr = currentNode->gScore + c.cost ---
    ; Fetch currentNode->gScore
    ADD R6 R3 M$[g_score_low_offset]
    LDM R4 M$[R6++]
    STM R4 M$[Arg0]
    LDM R4 M$[R6]
    STM R4 M$[Arg1]
    ; Fetch edge cost (c.cost) from neighbor element index tracking
    LDM R0 M$[Temp_Neighbor_Ptr]
    SUB R0 R0 0x0004                 ; Wind back to grab connection cost offset
    LDM R4 M$[R0++]
    STM R4 M$[Arg2]
    LDM R4 M$[R0]
    STM R4 M$[Arg3]
    CAL FP_ADD
    LDM R4 M$[Ret0]                  ; Track Gscr inside memory slots
    STM R4 M$[Gscr_Low]
    LDM R4 M$[Ret1]
    STM R4 M$[Gscr_High]

    ; --- Step B: Hscr = Heuristic(c.target, end) ---
    LDM R4 M$[Active_Target_Low]
    LDM R5 M$[Active_Target_High]
    STM R4 M$[Arg0]                  ; Arg0/1 = c.target
    STM R5 M$[Arg1]
    LDM R4 M$[Buffer1]               ; Arg2/3 = End node
    STM R4 M$[Arg2]
    ; (Assuming standard page for end pointer layout)
    CAL calc_heuristic
    LDM R4 M$[Ret0]
    STM R4 M$[Hscr_Low]
    LDM R4 M$[Ret1]
    STM R4 M$[Hscr_High]

    ; --- Step C: Fscr = Gscr + Hscr ---
    LDM R4 M$[Gscr_Low]
    LDM R5 M$[Gscr_High]
    STM R4 M$[Arg0]
    STM R5 M$[Arg1]
    LDM R4 M$[Hscr_Low]
    LDM R5 M$[Hscr_High]
    STM R4 M$[Arg2]
    STM R5 M$[Arg3]
    CAL FP_ADD
    LDM R4 M$[Ret0]
    STM R4 M$[Fscr_Low]
    LDM R4 M$[Ret1]
    STM R4 M$[Fscr_High]

    ; --- Step D: Evaluation and Node Memory Commit ---
    ; Check if c.target->gScore is more expensive or unvisited
    LDM R4 M$[Active_Target_Low]
    LDM R5 M$[Active_Target_High]
    EAM.SET R5
    ADD R4 R4 M$[g_score_low_offset]
    LDM R6 M$[R4++]                  ; Read existing node gScore
    STM R6 M$[Arg2]
    LDM R6 M$[R4]
    STM R6 M$[Arg3]
    
    LDM R4 M$[Gscr_Low]              ; Pass new calculated Gscr
    STM R4 M$[Arg0]
    LDM R4 M$[Gscr_High]
    STM R4 M$[Arg1]
    CAL FP_SUBTRACT
    LDM R4 M$[Ret1]                  ; Check comparison flags

    STJ .update_neighbor_node
    JLT R4 0x0000                    ; If New Gscr < Old Gscore, update node!
    
    ; Check if node is unvisited status (0x0000)
    LDM R4 M$[Active_Target_Low]
    ADD R6 R4 M$[status_offset]
    LDM R6 M$[R6]
    STJ .skip_node_update
    JNE R6 0x0000                    ; If already visited and not cheaper, skip update

.update_neighbor_node:
    ; Commit new metrics directly to neighbor node structure memory locations
    LDM R4 M$[Active_Target_Low]
    LDM R5 M$[Active_Target_High]
    EAM.SET R5
    
    ; Write gScore, hScore, fScore, and assign previous = currentNode (R3)
    ; ... [Data commit stores go here] ...
    
    ; Push neighbor to open list if it was completely unvisited
    ; ... [Open array index append logic goes here] ...

.skip_node_update:
    ; Restore our neighborhood looping index registers safely
    LDM R0 M$[Temp_Neighbor_Ptr]
    LDM R2 M$[Temp_Neighbor_Bank]
    LDM R4 M$[max_connections_bytes]
    ADD R1 R4 R0

.next_neighbor:
    STJ .neighbor_loop
JMP ; Advance to next neighbor direction calculation
.neighbors_done:
STJ big_while
JMP ; Step back to search the open list completely again
; =====================================================================
; 5. PATH RECONSTRUCTION & PIPELINE EPILOGUE
; =====================================================================
.build_path:
LDM R4 M$[Buffer1] ; Load End node tracking registers
STJ .earlyExit
JEQ R4 0x0000 ; Trace back via parent nodes to populate path
.earlyExit:
RET ; Return context path execution complete

Clone this wiki locally