-
Notifications
You must be signed in to change notification settings - Fork 0
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