So obviously, (just for posterity) the way you chain hooks is that you first back up a current hook's address and page when you install your hook. In your hook, you can either choose to act on the input data, or, where you would normally leave the hook and give control back to the TI-OS, you instead swap pages to the previous hook's page, then call into it. You of course need to reset the page when you return and pass along whatever it does. And needless to say, this hook-swapping code would have to be somewhere outside of $4000 to $8000, specifically, somewhere in RAM.
As for
being the one chained, you can easily detect that by checking the RAM location for your type of hook. For example, if your hook is a GetCSCHook, the following code would determine whether this hook is the current base GetCSCHook or has been chained through another hook (fyi, the base RAM location for a GetCSCHook is $9B88):
Code: GetCSCHookAddress .equ $9B88
MyGetCSCHook:
.db $83
;(code)
call IsThisGetCSCBaseHook
call nz,WeAreChained
;(more code)
ret
IsThisGetCSCBaseHook:
ld hl,GetCSCHookAddress
ld b,(hl)
in a,(6)
cp b
ret nz
inc hl
ld a,(hl) ;next 4 lines are essentially bcall(_ldhlind)
inc hl
ld h,(hl)
ld l,a
ld de,MyGetCSCHook
bcall(_cphlde)
ret ;nz set if not the same, z set if the same
Usual disclaimer: just made this up on the spot, I think it works.