; Minimal GS/OS dispatcher stub at $E100A8.  Native, M=0, X=0.
;
; Real GS/OS uses INLINE-form dispatch at $E100A8: the JSL is
; followed by 6 inline bytes (2-byte callNum + 4-byte pBlock LONG)
; and the dispatcher bumps the return PC by +6 to skip them.  The
; stub mirrors that contract so it can stand in for real GS/OS
; on a sysless smoke harness.
;
; On entry (after caller's JSL $E100A8):
;   S+1=PCL, S+2=PCH, S+3=PBR (the JSL return triplet, also the
;   address of the inline callNum WORD followed by the pBlock LONG).
;
; The stub reads the inline pBlock LONG (low 24 bits = bank:offset)
; via DP[$E4..$E6] long-indirect, writes $42 to *parm, bumps the
; return PC by +6 so the caller's RTL skips the inline operands,
; and returns A=0 (success).
;
; NOTE: This file is consumed two different ways:
;   1. runInMameWithGsosStub.sh assembles a hand-rolled byte sequence
;      (STUB_HEX) and writes it to $E100A8 from Lua at frame 30.  The
;      symbols below are not used in that path.
;   2. As a stand-in object file in a future link mode where the
;      dispatcher is the universal-success stub instead of the real
;      wrappers in iigsGsos.s.  In that mode, __gsosIsRealImpl below
;      is the source of truth for libc.c's __gsosAvailable().
	.text
	; --- read inline pBlock long ptr at [PBR:PCL+2] ---------------
	; PCL/PCH/PBR are at S+1..S+3 from JSL.  The callNum WORD sits
	; at PBR:PCL+1 (we need +1 because the JSL return is "next-byte
	; after JSL" minus one).  The pBlock LONG follows at PBR:PCL+3.
	; We use DP[$E4..$E6] as scratch (caller's $E0..$E3 zone is
	; reserved for libgcc ptr32 deref idiom).
	php                       ; save P
	rep #0x30                 ; M=16, X=16 -- match caller mode
	pha                       ; save A
	phy                       ; save Y
	; --- compute inline ptr address into $E4..$E6 (PBR:PC) --------
	; Stack at this point (M=16, after PHP/PHA/PHY pushed total 5
	; bytes -- 1+2+2):
	;   S+1..S+2 = saved Y
	;   S+3..S+4 = saved A
	;   S+5      = saved P
	;   S+6..S+7 = PCL/PCH (return PC = byte AFTER the JSL operand
	;              == first byte of the inline callNum WORD)
	;   S+8      = PBR
	lda 6, s                  ; A = 16-bit JSL return PC (= last byte
	                          ; of the JSL operand; +1 = first byte
	                          ; of the inline callNum WORD).  65816
	                          ; JSL/JSR push PC-1, not PC.
	sta 0xe4
	sep #0x20
	lda 8, s                  ; PBR byte
	sta 0xe6
	rep #0x20
	; Inline layout (offsets relative to JSL retPC at $E4):
	;   +1 .. +2 = callNum WORD (ignored -- universal-success stub)
	;   +3 .. +4 = pBlock LONG low 16  (offset)
	;   +5 .. +6 = pBlock LONG high 16 (bank in low byte, pad=0)
	; Read both halves via long-indirect-Y deref.
	ldy #0x3
	lda [0xe4], y             ; pBlock low 16 (offset)
	sta 0xe8
	ldy #0x5
	lda [0xe4], y             ; pBlock high 16 (bank in low byte,
	                          ; pad in high byte; pad always 0)
	sta 0xea
	; --- *(parm) = $42 -------------------------------------------
	ldy #0
	sep #0x20
	.a8
	lda #0x42
	sta [0xe8], y             ; *(pBlock) = $42 via long indirect
	rep #0x20
	.a16
	; --- bump return PC by +6 to skip the inline operands ---------
	lda 6, s
	clc
	adc #0x6
	sta 6, s                  ; PCL/PCH adjusted; +6 fits in 16 bits
	                          ; (no carry to PBR for the small jump)
	; --- restore and return A=0 -----------------------------------
	ply
	pla
	plp
	lda #0                    ; status = 0
	rtl

; __gsosIsRealImpl — companion sentinel to iigsGsos.s's symbol.  In
; this file the value is 0, so when a program links the stub object
; instead of the real GS/OS wrappers, libc.c's __gsosAvailable()
; returns 0 and fopen-via-GS/OS short-circuits cleanly instead of
; lying about success through the universal-success dispatcher.
;
; NOTE: this file does NOT define per-call symbols (gsosOpen, gsosRead,
; gsosWrite, gsosClose, gsosGetEOF, gsosSetEOF, gsosSetMark, gsosGetMark,
; gsosCreate, gsosDestroy, gsosChangePath, gsosGetPrefix, gsosGetFileInfo,
; gsosGetDirEntry).  libc.c declares those as
; undefined-weak, so when the stub is linked instead of iigsGsos.o
; they resolve to address 0 -- the libc-side callers all gate through
; __gsosAvailable() and short-circuit before dereferencing them.  Any
; new GS/OS class-1 wrapper added to iigsGsos.s follows the same
; pattern automatically; no changes to this file are needed per call.
	.globl __gsosIsRealImpl
__gsosIsRealImpl:
	.word 0
