TickEvents 7.64 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 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
; 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
; c) Fix RemoveTickerEvent to add this nodes time onto the next one
; 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

; In :  R0 is (signed) number of centiseconds
;       R1 is address to call
;       R2 is value of R12 to pass to code

CallAfter_Code   ROUT
        MOV     r10, #0
TickTockCommon
        Push    "r0-r3, lr"
        CMP     r0, #0
        BLE     %FT99

38 39
  [ ChocolateSysHeap
        ASSERT  ChocolateTKBlocks = ChocolateBlockArrays + 8
Jeffrey Lee's avatar
Jeffrey Lee committed
40
        LDR     r3,=ZeroPage+ChocolateBlockArrays
41 42 43 44 45
        LDR     r3,[r3,#8]
        BL      ClaimChocolateBlock
        MOVVS   r3, #TickNodeSize
        BLVS    ClaimSysHeapNode
  |
Neil Turton's avatar
Neil Turton committed
46 47
        MOV     r3, #TickNodeSize
        BL      ClaimSysHeapNode
48
  ]
Neil Turton's avatar
Neil Turton committed
49 50 51 52 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
        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

CallEvery_Code
        ADD     r10, r0, #1             ; compensate for n+1 bug
        B       TickTockCommon

; 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

Kevin Bracey's avatar
Kevin Bracey committed
114 115
        Push    "r0,r2"
        PHPSEI  r2
Jeffrey Lee's avatar
Jeffrey Lee committed
116
        LDR     r10, =ZeroPage+TickNodeChain
Neil Turton's avatar
Neil Turton committed
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
01
        MOV     r11, r10
        LDR     r10, [r11, #TickNodeLink]
        CMP     r10, #0
        BEQ     %FT02                           ; end of chain
        LDR     r12,  [r10, #TickNodeLeft]
        SUBS    r0, r0, r12
        BGE     %BT01
        ADD     r0, r0, r12
        SUB     r12, r12, r0
        STR     r12, [r10, #TickNodeLeft]
02
        STR     r1, [r11, #TickNodeLink]
        STR     r0, [r1, #TickNodeLeft]
        STR     r10, [r1, #TickNodeLink]

Kevin Bracey's avatar
Kevin Bracey committed
133 134 135
        PLP     r2
        Pull    "r0,r2"
        MOV     pc, lr
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 148 149 150 151

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

        LDR     r2, [r1, #TickNodeLeft]
        SUBS    r2, r2, #1
        STR     r2, [r1, #TickNodeLeft]
        MOVGT   pc, lr                          ; nothing to call yet (was MOVPL)

        Push    "lr"                            ; save IRQ_lr
 [ TickIrqReenter
Kevin Bracey's avatar
Kevin Bracey committed
152
        WritePSRc SVC_mode+I_bit, r10           ; switch to SVC mode, IRQ's off
Neil Turton's avatar
Neil Turton committed
153 154 155 156 157 158 159 160 161 162 163 164
        NOP
        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
        MOV     lr, pc
        MOV     pc, r11                         ; call event handler

        LDR     r0, [r1, #TickNodeRedo]
        CMP     r0, #0                          ; CallEvery?
Kevin Bracey's avatar
Kevin Bracey committed
165 166 167 168
        BLE     %FT05

        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

Kevin Bracey's avatar
Kevin Bracey committed
173
        WritePSRc SVC_mode, r2                  ; 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
  ]
Kevin Bracey's avatar
Kevin Bracey committed
188
        WritePSRc SVC_mode+I_bit, r1            ; IRQ's off again
Neil Turton's avatar
Neil Turton committed
189 190 191 192 193 194 195 196 197 198 199 200

; Check for more events down the list
10
        LDR     r1, [r3, #TickNodeLink]         ; get top of list
        CMP     r1, #0                          ; list empty?
        BEQ     %FT02                           ; yes then exit

        LDR     r0, [r1, #TickNodeLeft]
        CMP     r0, #0                          ; timed out?
        BLE     %BT01                           ; yes then jump
02
        Pull    "lr"                            ; restore SVC_lr
Kevin Bracey's avatar
Kevin Bracey committed
201
        WritePSRc IRQ_mode+I_bit, r10           ; back to IRQ mode
Neil Turton's avatar
Neil Turton committed
202 203 204 205 206
        NOP
        Pull    "pc"                            ; pull IRQ_lr from IRQ stack

RemoveTickerEvent_Code
; R0 is address of code to remove, R1 the R12 value
Kevin Bracey's avatar
Kevin Bracey committed
207
        WritePSRc SVC_mode+I_bit, r10
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