; Copyright 1996 Acorn Computers Ltd
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
;     http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
; > s.poll

; ****************************************************************************
; * This source file was written by Acorn Computers Limited. It is part of   *
; * the "cwimp" library for writing applications in C for RISC OS. It may be *
; * used freely in the creation of programs for Archimedes. It should be     *
; * used with Acorn's objasm assembler.                                      *
; *                                                                          *
; * No support can be given to programmers using this code and, while we     *
; * believe that it is correct, no correspondence can be entered into        *
; * concerning behaviour or bugs.                                            *
; *                                                                          *
; * Upgrades of this code may or may not appear, and while every effort will *
; * be made to keep such upgrades upwards compatible, no guarantees can be   *
; * given.                                                                   *
; ****************************************************************************

; Title  : s.poll
; Purpose: interface to wimp poll for C programs
; Version: 0.1               created
;          0.2 SKS 22-Nov-88 made SWI Poll use X-form SWI
;              ECN 08-May-91 '#ifndefed' out unused ROM functions

        GBLL    ModeMayBeNonUser
ModeMayBeNonUser   SETL  {FALSE}

        GET     rlib.s.asmdefs
        GET     s.h_Brazil
        GET     Hdr:Wimp

        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
        FunctionEntry "v1-v2", frame
        MOV     v2, a1
        MOV     v1, a2

        BL      |_kernel_fpavailable|
        TEQ     a1, #0
        LDRNE   a1, =poll_preserve_fp
        LDRNE   a1, [a1]
        TEQNE   a1, #0
        BLNE    save_fp_state
        MOV     lr, a1

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

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

        CMP     lr, #0
        BLNE    restore_fp_state

        Return  "v1-v2", "fpbased"

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

        EXPORT  wimp_pollidle
wimp_pollidle
        FunctionEntry "v1-v3", frame
        MOV     v2, a1
        MOV     v1, a2
        MOV     v3, a3

        BL      |_kernel_fpavailable|
        TEQ     a1, #0
        LDRNE   a1, =poll_preserve_fp
        LDRNE   a1, [a1]
        TEQNE   a1, #0
        BLNE    save_fp_state
        MOV     lr, a1

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

        CMP     lr, #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
        Return  "v1-v3", "fpbased"

; 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

        [ :LNOT:UROM
        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
        ]

        [ :LNOT:UROM
        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