;/************************************************************************/
;/*  Acorn Computers Ltd, 1992.                                         */
;/*                                                                      */
;/* This file forms part of an unsupported source release of RISC_OSLib. */
;/*                                                                      */
;/* It may be freely used to create executable images for saleable       */
;/* products but cannot be sold in source form or as an object library   */
;/* without the prior written consent of Acorn Computers Ltd.            */
;/*                                                                      */
;/* If this file is re-distributed (even if modified) it should retain   */
;/* this copyright notice.                                               */
;/*                                                                      */
;/************************************************************************/

; Title  : s.poll
; Purpose: interface to wimp poll for C programs
; History: IDJ: 07-Feb-92: prepared for source release


a1 RN 0
a2 RN 1
a3 RN 2
a4 RN 3
v1 RN 4
v2 RN 5
v3 RN 6
v4 RN 7
v5 RN 8
v6 RN 9
sl RN 10
fp RN 11
ip RN 12
sp RN 13
lk RN 14
lr RN 14
pc RN 15

f0 FN 0
f1 FN 1
f2 FN 2
f3 FN 3
f4 FN 4
f5 FN 5
f6 FN 6
f7 FN 7

XPoll     * (1 :SHL: 17) :OR: &400C7
XPollIdle * (1 :SHL: 17) :OR: &400E1

        AREA |C$$code|, CODE, READONLY

|x$codeseg|

        IMPORT  |_kernel_fpavailable|
        EXPORT  wimp_poll

; os_error * wimp_poll(wimp_emask mask, wimp_eventstr * result) ;
; a1 is poll mask, a2 is pointer to event structure

wimp_poll
        MOV     ip, sp
        STMFD   sp!, {v1,v2,fp,ip,lk,pc}
        SUB     fp, ip, #4
        MOV     v2, a1
        MOV     v1, a2

        LDR     a1, =poll_preserve_fp
        LDR     a1, [a1]
        CMP     a1, #0
        BEQ     nopreserve1
        BL      |_kernel_fpavailable|
        CMP     a1, #0
        BLNE    save_fp_state
nopreserve1
        MOV     lk, a1

        MOV     a1, v2                    ; restore mask
        ADD     a2, v1, #4                ; point at eventstr->data
        SWI     XPoll

        SUB     a2, a2, #4                ; point back at eventstr
        STR     a1, [a2, #0]              ; set reason code
        MOVVC   a1, #0                    ; no error

        CMP     lk, #0
        BLNE    restore_fp_state

        LDMEA   fp, {v1,v2,fp,sp,pc}


; os_error *wimp_pollidle(wimp_emask mask, wimp_eventstr *result, int earliest)
; a1 mask, a2 eventstr, a3 earliest

        EXPORT  wimp_pollidle
wimp_pollidle
        MOV     ip, sp
        STMFD   sp!, {v1,v2,v3,fp,ip,lk,pc}
        SUB     fp, ip, #4
        MOV     v2, a1
        MOV     v1, a2
        MOV     v3, a3

        LDR     a1, =poll_preserve_fp
        LDR     a1, [a1]
        CMP     a1, #0
        BEQ     nopreserve2
        BL      |_kernel_fpavailable|
        CMP     a1, #0
        BLNE    save_fp_state
nopreserve2
        MOV     lk, a1

        MOV     a1, v2                    ; restore mask
        ADD     a2, v1, #4                ; point at eventstr->data
        MOV     a3, v3                    ; restore time
        SWI     XPollIdle

        CMP     lk, #0
        BLNE    restore_fp_state

        SUB     a2, a2, #4                ; point back at eventstr
        STR     a1, [a2, #0]              ; set reason code
        MOVVC   a1, #0                    ; no error
        LDMEA   fp, {v1,v2,v3,fp,sp,pc}

; Only f4..f7 defined preserved over procedure call
; can corrupt a2-a4
save_fp_state
        RFS     a2                      ; read FP status
        STMFD   sp!, {a2}
        MOV     a2, #0
        WFS     a2
        SUB     sp, sp, #4*12           ; emulated a lot faster than writeback
        STFE    f4, [sp, #0*12]
        STFE    f5, [sp, #1*12]
        STFE    f6, [sp, #2*12]
        STFE    f7, [sp, #3*12]
        MOV     pc, lr

; v1, v2 trashable
restore_fp_state
        MOV     v1, #0
        WFS     v1
        LDFE    f4, [sp, #0*12]
        LDFE    f5, [sp, #1*12]
        LDFE    f6, [sp, #2*12]
        LDFE    f7, [sp, #3*12]
        ADD     sp, sp, #4*12           ; emulated a lot faster than writeback
        LDMFD   sp!, {v1}
        WFS     v1
        MOV     pc, lr


        EXPORT  wimp_save_fp_state_on_poll
wimp_save_fp_state_on_poll
        LDR   a1, =poll_preserve_fp
        MOV   a2, #1
        STR   a2, [a1]
        MOV   pc, lr

        EXPORT  wimp_corrupt_fp_state_on_poll
wimp_corrupt_fp_state_on_poll
        LDR   a1, =poll_preserve_fp
        MOV   a2, #0
        STR   a2, [a1]
        MOV   pc, lr

        LTORG

    AREA |C$$data|
|x$dataseg|

poll_preserve_fp  DCD  1

    END
