65816-llvm-mos/runtime/src/gnoGsos.s
Scott Duensing 9e53e5fd38 GNO Support
2026-05-29 15:43:28 -05:00

42 lines
1.5 KiB
ArmAsm

; gnoGsos.s — GS/OS calls from inside a GNO/ME process.
;
; GNO patches GS/OS entry $E100A8 to its interceptor (OurGSOS in
; kern/gno/gsos.asm), which reads the call number + parameter-block
; pointer from the 6 INLINE bytes after the JSL and bumps the return
; address +6 to skip them:
;
; jsl $E100A8
; dc i2 callNum ; 2 bytes
; dc i4 pBlockPtr ; 4 bytes (bank : offset)
; <-- OurGSOS returns here
;
; The plain stack-based form (callNum in X, pBlock pushed) that bare
; GS/OS accepts does NOT work under GNO. We self-modify the inline
; callNum + pBlock operands, then dispatch.
;
; __gnoGsosCall(void *pBlock, unsigned short callNum) -> u16 error
; C ABI: arg0 (pBlock ptr32) in A:X (A=offset, X=bank); arg1
; (callNum i16) at (4,s). Returns the GS/OS error in A (0 = OK).
.text
.globl __gnoGsosCall
__gnoGsosCall:
rep #0x30
sta __gnoPBlock ; inline pBlock offset (low 16)
txa
sta __gnoPBlock+2 ; inline pBlock bank+pad (X = bank : pad)
lda 4, s ; callNum from the stack
sta __gnoCallNum ; inline callNum
lda 0xb4 ; restore GNO's per-process DP
tcd
jsl 0xe100a8
__gnoCallNum:
.word 0 ; patched: GS/OS call number
__gnoPBlock:
.long 0 ; patched: param-block pointer
; --- OurGSOS returns here (return addr bumped +6) ---
tay ; Y = error (survives DP change)
lda #0
tcd ; DP := 0 for the C caller
tya
rtl