42 lines
1.5 KiB
ArmAsm
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
|