TickEvents 8.03 KB
Newer Older
Neil Turton's avatar
Neil Turton committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
; 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.
;
        TTL   => TickEvents

; This file revised by TMD 28-Jan-94 to
; a) Correct internals to time n ticks not n+1
; b) Change externals to add 1 to compensate for user subtracting 1
20
; c) Fix RemoveTickerEvent to add this node's time onto the next one
Neil Turton's avatar
Neil Turton committed
21 22 23 24 25 26
; These fix bug MED-02498.

; There are two (centisecond) ticker SWIs :
; SWI CallAfter calls the given address once, after the given number of ticks
; SWI CallEvery  "     "    "    "      every N centiseconds

27
; In :  R0 is unsigned number of centiseconds
Neil Turton's avatar
Neil Turton committed
28 29 30
;       R1 is address to call
;       R2 is value of R12 to pass to code

31 32 33
CallEvery_Code
        ADD     r10, r0, #1             ; compensate for n+1 bug
        B       TickTockCommon
Neil Turton's avatar
Neil Turton committed
34 35 36 37
CallAfter_Code   ROUT
        MOV     r10, #0
TickTockCommon
        Push    "r0-r3, lr"
38 39 40
        ADD     r14, r0, #1024
        CMP     r14, #1024
        BLS     %FT99                   ; reject 0 and >= &FFFFFC00
Neil Turton's avatar
Neil Turton committed
41

42 43
  [ ChocolateSysHeap
        ASSERT  ChocolateTKBlocks = ChocolateBlockArrays + 8
Jeffrey Lee's avatar
Jeffrey Lee committed
44
        LDR     r3,=ZeroPage+ChocolateBlockArrays
45 46 47 48 49
        LDR     r3,[r3,#8]
        BL      ClaimChocolateBlock
        MOVVS   r3, #TickNodeSize
        BLVS    ClaimSysHeapNode
  |
Neil Turton's avatar
Neil Turton committed
50 51
        MOV     r3, #TickNodeSize
        BL      ClaimSysHeapNode
52
  ]
Neil Turton's avatar
Neil Turton committed
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
        BVS     %FT97

        MOV     r3, r2
        LDMFD   stack, {r0-r2}
        STR     r1,  [r3, #TickNodeAddr]
        STR     r10, [r3, #TickNodeRedo]
        STR     r2,  [r3, #TickNodeR12]
        MOV     r1, r3

        ADD     r0, r0, #1              ; compensate for n+1 bug
        BL      InsertTickerEvent

        Pull    "r0-r3, lr"
        ExitSWIHandler

99      ADR     r0, ErrorBlock_BadTime
      [ International
        BL      TranslateError
      ]
97
        ADD     sp, sp, #1*4            ; junk old R0
        Pull    "r1-r3, lr"
        B       SLVK_SetV

        MakeErrorBlock BadTime


; Data structure :
; chain of nodes
;
;       +----------------------------------+
;       |   Link to next node or 0         |
;       +----------------------------------+
;       |   Reload flag                    |
;       +----------------------------------+
;       |   Address to call                |
;       +----------------------------------+
;       |   Value of R12                   |
;       +----------------------------------+
;       |   No of ticks to go before call  |
;       +----------------------------------+
;
; The head node's no of ticks is decremented until 0
;  Subsequent nodes contain the no of ticks to wait when they reach the
;  chain head.
; If the reload flag is non-0, the node is reinserted at that number of ticks
; down the chain after every use.

             ^  0
TickNodeLink #  4        ;
TickNodeRedo #  4        ; These are together
TickNodeAddr #  4        ;
TickNodeR12  #  4        ;  so can LDM them

TickNodeLeft #  4

TickNodeSize #  0

InsertTickerEvent   ROUT
; R1 is node pointer, R0 ticks to wait
; R10-R12 corrupted

115 116
        Push    "r0,lr"
        PHPSEI  r14
Jeffrey Lee's avatar
Jeffrey Lee committed
117
        LDR     r10, =ZeroPage+TickNodeChain
Neil Turton's avatar
Neil Turton committed
118 119 120 121 122 123
01
        MOV     r11, r10
        LDR     r10, [r11, #TickNodeLink]
        CMP     r10, #0
        BEQ     %FT02                           ; end of chain
        LDR     r12,  [r10, #TickNodeLeft]
124 125 126
        CMP     r12, r0
        SUBLS   r0, r0, r12
        BLS     %BT01                           ; node R10 is earlier (or equal) to node R1
Neil Turton's avatar
Neil Turton committed
127 128 129 130 131 132 133
        SUB     r12, r12, r0
        STR     r12, [r10, #TickNodeLeft]
02
        STR     r1, [r11, #TickNodeLink]
        STR     r0, [r1, #TickNodeLeft]
        STR     r10, [r1, #TickNodeLink]

134 135
        PLP     r14
        Pull    "r0,pc"
Neil Turton's avatar
Neil Turton committed
136 137 138

ProcessTickEventChain  ROUT
; R0-R3, R10-R12 corruptible
Jeffrey Lee's avatar
Jeffrey Lee committed
139
        LDR     r3, =ZeroPage+TickNodeChain
Neil Turton's avatar
Neil Turton committed
140 141 142 143 144 145 146 147

        LDR     r1, [r3, #TickNodeLink]
        CMP     r1, #0
        MOVEQ   pc, lr                          ; no timers

        LDR     r2, [r1, #TickNodeLeft]
        SUBS    r2, r2, #1
        STR     r2, [r1, #TickNodeLeft]
148
        MOVHI   pc, lr                          ; nothing to call yet (HI to cope with ordinary 1 -> 0 transition, and 0 -> -1 transition if re-entered while processing two or more events which are due to fire at the same time)
Neil Turton's avatar
Neil Turton committed
149 150

        Push    "lr"                            ; save IRQ_lr
151
        MSR     CPSR_c, #SVC32_mode+I32_bit     ; switch to SVC mode, IRQ's off
Neil Turton's avatar
Neil Turton committed
152 153 154 155 156
        Push    "lr"                            ; save SVC_lr
01
        LDMIA   r1, {r2, r10, r11, r12}         ; load next ptr, redo state,
                                                ;     address and R12val
        STR     r2, [r3]                        ; de-link from chain
157
      [ NoARMv5
Neil Turton's avatar
Neil Turton committed
158 159
        MOV     lr, pc
        MOV     pc, r11                         ; call event handler
160 161 162
      |
        BLX     r11                             ; call event handler
      ]
Neil Turton's avatar
Neil Turton committed
163

164
        MOVS    r0, r10                         ; CallEvery?
165
        BEQ     %FT05
Kevin Bracey's avatar
Kevin Bracey committed
166 167 168

        BL      InsertTickerEvent               ; yes, then re-insert timer
        B       %FT10
Neil Turton's avatar
Neil Turton committed
169

Kevin Bracey's avatar
Kevin Bracey committed
170
05
Neil Turton's avatar
Neil Turton committed
171 172
; Return spent ticker node to heap

173
        MSR     CPSR_c, #SVC32_mode             ; IRQ's ON for the  S L O W  bit
Neil Turton's avatar
Neil Turton committed
174
        MOV     r2, r1                          ; R2->node to free
175 176
  [ ChocolateSysHeap
        ASSERT  ChocolateTKBlocks = ChocolateBlockArrays + 8
Jeffrey Lee's avatar
Jeffrey Lee committed
177
        LDR     r1,=ZeroPage+ChocolateBlockArrays
178 179 180 181 182 183
        LDR     r1,[r1,#8]
        BL      FreeChocolateBlock
        LDRVS   r1, =SysHeapStart
        MOVVS   r0, #HeapReason_Free
        SWIVS   XOS_Heap
  |
Neil Turton's avatar
Neil Turton committed
184 185 186
        LDR     r1, =SysHeapStart
        MOV     r0, #HeapReason_Free
        SWI     XOS_Heap
187
  ]
Neil Turton's avatar
Neil Turton committed
188

189
; Check for more events at the same level in the list
Neil Turton's avatar
Neil Turton committed
190
10
191 192
        MSR     CPSR_c, #SVC32_mode+I32_bit     ; IRQ's off again (after returning node to heap, or after naughty CallEvery exits with IRQs on)

Neil Turton's avatar
Neil Turton committed
193 194 195 196 197
        LDR     r1, [r3, #TickNodeLink]         ; get top of list
        CMP     r1, #0                          ; list empty?
        BEQ     %FT02                           ; yes then exit

        LDR     r0, [r1, #TickNodeLeft]
198 199
        CMP     r0, #0                          ; zero time delta?
        BEQ     %BT01                           ; yes then jump
Neil Turton's avatar
Neil Turton committed
200 201
02
        Pull    "lr"                            ; restore SVC_lr
202
        MSR     CPSR_c, #IRQ32_mode+I32_bit     ; back to IRQ mode
Neil Turton's avatar
Neil Turton committed
203 204 205 206
        Pull    "pc"                            ; pull IRQ_lr from IRQ stack

RemoveTickerEvent_Code
; R0 is address of code to remove, R1 the R12 value
207
        MSR     CPSR_c, #SVC32_mode+I32_bit
Jeffrey Lee's avatar
Jeffrey Lee committed
208
        LDR     r10, =ZeroPage+TickNodeChain
Neil Turton's avatar
Neil Turton committed
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
01
        LDR     r11, [r10]
        CMP     r11, #0
        ExitSWIHandler EQ
        LDR     r12, [r11, #TickNodeAddr]
        CMP     r12, r0
        LDREQ   r12, [r11, #TickNodeR12]
        CMPEQ   r12, r1
        MOVNE   r10, r11
        BNE     %BT01

        Push    "r0-r2, lr"
        MOV     r2, r11
        LDR     r11, [r11, #TickNodeLink]       ; prev->link = this->link
        STR     r11, [r10]

        TEQ     r11, #0                         ; if next node exists
        LDRNE   r14, [r11, #TickNodeLeft]       ; then add our time-to-go onto its
        LDRNE   r0, [r2, #TickNodeLeft]
        ADDNE   r14, r14, r0
        STRNE   r14, [r11, #TickNodeLeft]

231 232
  [ ChocolateSysHeap
        ASSERT  ChocolateTKBlocks = ChocolateBlockArrays + 8
Jeffrey Lee's avatar
Jeffrey Lee committed
233
        LDR     r1,=ZeroPage+ChocolateBlockArrays
234 235 236 237
        LDR     r1,[r1,#8]
        BL      FreeChocolateBlock
        BLVS    FreeSysHeapNode
  |
Neil Turton's avatar
Neil Turton committed
238
        BL      FreeSysHeapNode
239
  ]
Neil Turton's avatar
Neil Turton committed
240 241 242 243
        Pull    "r0-r2, lr"
        B       %BT01

ReadMetroGnome
Jeffrey Lee's avatar
Jeffrey Lee committed
244
        LDR     r0, =ZeroPage
Neil Turton's avatar
Neil Turton committed
245 246 247 248 249 250
        LDR     r0, [r0, #MetroGnome]
        ExitSWIHandler

        LTORG

        END