; s.QuickCaret
;
; QuickCaret written by Richard Millican...
; Ported to assembler by Tackline (aka Thomas Hawtin)
; Version 1.01 (12/06/93)
;
; === Version 1.01a (Wed 04th September 1996) by Ernie Ong ===
; QuickCaret now works properly when a new window is opened but
; isn't below the (mouse) pointer. The new window will have the
; caret in such cases. Otherwise, the operation is identical as
; before.
; All the changes made by me are marked with "Ernie" either at
; or near the occurrences.

Xbit                    *       &20000

OS_GetEnv               *       &00010
OS_ExitAndDie           *       &00050
XOS_Module              *       &0001E :OR: Xbit
OS_ReadMonotonicTime    *       &00042
XWimp_Initialise        *       &400C0 :OR: Xbit
Wimp_PollIdle           *       &400E1
Wimp_GetPointerInfo     *       &400CF
Wimp_SetCaretPosition   *       &400D2
Wimp_GetCaretPosition   *       &400D3
Wimp_CloseDown          *       &400DD

wimp_ESEND              *       17
wimp_ESENDWANTACK       *       18
wimp_msghdr_action      *       16
wimp_MCLOSEDOWN         *       0
wimp_mousestr_whandle   *       12
wimp_caretstr_w         *       0
Module_Claim            *       6

r0      RN      0
r1      RN      1
r2      RN      2
r3      RN      3
r4      RN      4
r5      RN      5
r6	RN	6	; Used to store the last pointer's whandle - Ernie
r12     RN      12
sp      RN      13
lr      RN      14
pc      RN      15

taskH           *       &100
wrkSize         *       &104

pollInterval    *       15              ; cs polling interval
					; slowed down - Ernie


;       AREA    |main|, CODE, READONLY


Module_BaseAddr
        DCD     RM_Start   -Module_BaseAddr
        DCD     RM_Init    -Module_BaseAddr
        DCD     RM_Die     -Module_BaseAddr
        DCD     RM_Service -Module_BaseAddr
        DCD     RM_Title   -Module_BaseAddr
        DCD     RM_HelpStr -Module_BaseAddr
        DCD     RM_HC_Table-Module_BaseAddr


RM_Init
        STMFD   sp!, {lr}
        LDR     r0, [r12]
        TEQ     r0, #0                  ; [r12] = 0 iff re-init
        MOVEQ   r0, #Module_Claim       ; w/s
        MOVEQ   r3, #wrkSize            ; size of claim
        SWIEQ   XOS_Module
        MOVEQ   r0, r2
        STREQ   r0, [r12]               ; store ptr in private word

        MOV     r1, #0                  ; w/s ptr
        STR     r1, [r0, #taskH]        ; reset task handle

        LDMFD   sp!, {pc}


RM_Die
        STMFD   sp!, {lr}

        LDR     r12, [r12]              ; w/s ptr

        LDR     r0, [r12, #taskH]       ; get task handle
        TEQ     r0, #0                  ; already running iff != 0
        LDRNE   r1, taskCode
        SWINE   Wimp_CloseDown          ; shut down
        MOVNE   r0, #0                  ; mark inactive
        STRNE   r0, [r12, #taskH]

        LDMFD   sp!, {pc}


RM_Service * Module_BaseAddr
RM_HC_Table * Module_BaseAddr


RM_Start
        LDR     sp, [r12]              ; w/s ptr
        ADD     sp, sp, #4             ; single entry stack
        BL      RM_Die

	MOV	r6, #-7			; Initialise r6 - Ernie
        LDR     r0, =200                ; Minimum Risc OS 2.00
        LDR     r1, taskCode
        ADR     r2, RM_Title
        SWI     XWimp_Initialise
        ADRVS   r3, RM_Title
        SWIVS   OS_ExitAndDie
        STR     r1, [r12, #taskH]

lp
        SWI     OS_ReadMonotonicTime
        ADD     r2, r0, #pollInterval   ; centiseconds
        MOV     r0, #0
        MOV     r1, r12
        SWI     Wimp_PollIdle

; check for close down message
        CMP     r0, #wimp_ESEND
        CMPNE   r0, #wimp_ESENDWANTACK
        LDREQ   r0, [r12, #wimp_msghdr_action]
        CMPEQ   r0, #wimp_MCLOSEDOWN 
        ADREQ   r3, RM_Title
        SWIEQ   OS_ExitAndDie

; see if pointer and caret are in different window
        SWI     Wimp_GetCaretPosition
        LDR     r5, [r12, #wimp_caretstr_w]
        SWI     Wimp_GetPointerInfo     ; r1 = r12
        LDR     r0, [r12, #wimp_mousestr_whandle]
        
        ; TEQ	r0, r5 ; Revision 1 - Ernie
        ; BEQ	lp ; Revision 1 - Ernie

; move caret
	; BEGIN  	Ernie changed the block below
	
	; TEQ	r0, r6		; pointer's whandle unchanged? ; Revision 1
	; BEQ	lp		; unchanged - leave now ; Revision 1

        CMP	r0, r5		; if (r0 = r5) - pointer & caret      together
        CMPNE	r0, r6		; OR (r0 = r6) - pointer & oldPointer together
        BEQ	lp		; then yield (ie Wimp_PollIdle)
        			; "together" == "with same window handle"
        
	; Removed "NE" condition for all instructions below -
	; too many to skip.
        MOV	r6, r0		; if diff whandle, store current whandle

                                      ; r0 = whandle
        MOV   r1, #-1                 ; no icon handle
        MOV   r2, #0                  ; off (0,0)
        MOV   r3, #0
        MOV   r4, #-1                 ; no height/flags
        MOV   r5, #-1                 ; no index into string
        SWI   Wimp_SetCaretPosition
        
        ; END  		Ernie changed the block above

        B     lp

taskCode
        =       "TASK"

RM_Title
        =       "QuickCaret\0"

RM_HelpStr
        =       ""
        		; "QuickCaret 1.01 (12 Jun 1993)\0" 
        	   	; This saves more memory - Ernie


        END
