;===========================
; SHDW_STRUCT
;===========================
shdw_struct:
    MOVE.W  #$0, -(A7)      ; function number (returns pointer to shdw_rec)
    TRAP    #15             ; D0 contains pointer to structure on return
    ADDQ.L  #2, A7          ; clean up stack
    RTS

;===========================
; SHDW_RECEIVE
;===========================
shdw_receive:
    MOVE.L  12(A6), -(A7)   ; push length of buffer  (length)
    MOVE.L  8(A6), -(A7)    ; push pointer to buffer (buffer)
    MOVE.W  16(A6), -(A7)   ; push transfer option   (mode)
    MOVE.W  #$1, -(A7)      ; push function number
    TRAP    #15
    ADDA.L  #$c, A7         ; clean up stack
    RTS

;===========================
; SHDW_SEND
;===========================
shdw_send:
    MOVE.L  12(A6), -(A7)   ; push length of file to send (moot for batch)
    MOVE.L  8(A6), -(A7)    ; push pointer to buffer
    MOVE.W  16(A6), -(A7)   ; push transfer option
    MOVE.W  #$2, -(A7)      ; push function number
    TRAP    #15
    ADDA.L  #$c, A7         ; clean up stack
    RTS

;===========================
; SHDW_ABORT
;===========================
shdw_abort:
    MOVE.W  #$3, -(A7)      ; function number (abort all transfers)
    TRAP    #15
    ADDQ.L  #2, A7          ; clean up stack
    RTS

;===========================
; SHDW_DIGITS
;===========================
shdw_digits:
    MOVE.W  #$4, -(A7)      ; function number (turn on on-screen count)
    TRAP    #15
    ADDQ.L  #2, A7          ; clean up stack
    RTS

;===========================
; SHDW_NODIGITS
;===========================
shdw_nodigits:
    MOVE.W  #$5, -(A7)      ; function number (turn off on-screen count)
    TRAP    #15
    ADDQ.L  #2, A7          ; clean up stack
    RTS

;===========================
; SHDW_BELL
;===========================
shdw_bell:
    MOVE.W  #$6, -(A7)      ; function number (turn on completion bell)
    TRAP    #15
    ADDQ.L  #2, A7          ; clean up stack
    RTS

;===========================
; SHDW_NOBELL
;===========================
shdw_nobell:
    MOVE.W  #$7, -(A7)      ; function number (turn off completion bell)
    TRAP    #15
    ADDQ.L  #2, A7          ; clean up stack
    RTS

;===========================
; SHDW_INIT
;===========================
shdw_init:
    MOVE.W  #$8, -(A7)      ; function number (call to restart or init)
    TRAP    #15             ; this function is not needed by user!
    ADDQ.L  #2, A7          ; clean up stack
    RTS

;===========================
; SHDW_DIAL
;===========================
shdw_dial:                  ; dial a number in background
    MOVE.L  20(A6), -(A7)   ; fail2 string
    MOVE.L  16(A6), -(A7)   ; fail1 string
    MOVE.L  12(A6), -(A7)   ; connect string
    MOVE.L  8(A6), -(A7)    ; number string (pass zero here to abort)
    MOVE.W  #$9, -(A7)      ; function number
    TRAP    #15
    ADDA.L  #$12, A7        ; clean up stack
    RTS

;===========================
; SHDW_CHECK
;===========================
shdw_check:                 ; this function checks for Shadow's presence
    CLR.L   -(A7)           ; must execute this code in
    MOVE.W  #$20, -(A7)     ; Supervisor mode
    TRAP    #1              ; GEMDOS
    ADDQ.L  #6, A7          ; pop stack

    CLR.L   D2              ; set to fail status
    MOVEA.L $42e, A0        ; get phys_top
    CMPA.L  #$400000, A0    ; is it 4 meg boundary?
    BEQ.B   leave           ; yep, bye
    MOVE.L  (A0), D1        ; nope, get what it points to
    CMP.W   #$dc, D1        ; is it $00DC (magic number)?
    BNE.B   leave           ; nope, bye
    TST.L   2(A0)           ; it is magic, but is transfer buffer allocated?
    BEQ.B   leave           ; nope, bye
    MOVE.L  #$1, D2         ; yes, so shadow is here, return a 1

leave:
    MOVE.L  D0, -(A7)       ; leave supervisor mode
    MOVE.W  #$20, -(A7)
    TRAP    #1
    ADDQ.L  #6, A7
    MOVE.L  D2, D0          ; return status, TRUE or FALSE
    RTS


