; > s.xpoll

; ****************************************************************************
; * 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




r0 RN 0
r1 RN 1
r2 RN 2
r3 RN 3
r4 RN 4
r5 RN 5
r6 RN 6
r7 RN 7
r8 RN 8
r9 RN 9
r10 RN 10
r11 RN 11
r12 RN 12
r13 RN 13
r14 RN 14
r15 RN 15



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_pollx

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

wimp_pollx
        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     nopreserve1
        BL      |_kernel_fpavailable|
        CMP     a1, #0
        BLNE    save_fp_state
nopreserve1
        MOV     lk, a1

        MOV     a4, v3

        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,v3,fp,sp,pc}


; os_error *wimp_pollidlex(wimp_emask mask,wimp_eventstr *result,
;                                              int earliest,int * pollword)

; a1 mask, a2 eventstr, a3 earliest

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

        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
        MOV     a4, v4

        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,v4,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
