Re: Unable to use the interval timer



On Sep 15, 11:05 am, Xavier <xlta...@xxxxxxxxx> wrote:
Hello everybody.

I need your help with a routine I'm unable to write properly.
The target machine is an A3000 (ARM2, RISC OS 3.1)
I want to use the Interval Timer which, unless I'm wrong, is the only
timer you can use to run a routine under interrupt every centisecond
(other timers will only run a routine at the fastest at 50th of a
second).

The trouble with the interval timer is that there is only one and
therefore there is liable to be contention between your software and
any others that may be using the interval timer. If you really need an
interrupt every centisecond then it would be better to claim the
ticker vector (TickerV = &1C instead of EventV = &10). This would
avoid the risk of fighting with other programs over the interval
timer, and would have the additional advantage of simplifying your
code.

I can't remember off the top of my head whether the interval-timer-
crossing-zero event is delivered in IRQ mode (never having used it
myself), but the fact that your routine is changing to SVC mode
suggests that it is. Therefore you have nothing to lose by using
TickerV instead of EventV.

So here is the code, with some comments.
Any idea where I'm wrong will help me.
Thanks in advance.
(To be run from BASIC, with 480 Kb of screen memory allocated in the
task display before entering BASIC)

REM >Timer

DIM Code 3000
FOR pass = 0 TO 2 STEP 2
P%=Code
[OPT pass

.Remove_Timer_Routine
MOV   R0,#&10
ADR   R1,Code_Timer
MOV   R2,#0
SWI   "OS_Release" ; PRM 1-68

MOV   R0,#13
MOV   R1,#5 ; PRM 1-145
SWI   "OS_Byte" ; PRM 1-148 Disables an event

MOV   PC,R14

;--------------------

.Code_Timer
STMFD R13!,{R0-R12,R14}

You aren't checking the event number (R0) and therefore your routine
will be executed when any event happens, not just the interval-timer-
crossed-zero event.

MOV   R9,PC
ORR   R8,R9,#3
TEQP  R8,#0
MOV   R0,R0

Of all your code, I would have thought that this merited some
explanatory comments.

;Should I reload the timer every time ?
;MOV   R0,#4
;ADR   R1,Counter_Block
;SWI &07 ; PRM 1-413 Write Interval Timer

You are ill-advised to use a software interrupt in an interrupt-driven
routine because of the danger of inadvertantly causing reentrancy.
What would happen if some code running in the foreground was already
in the middle of writing to the interval timer? It is usually safer to
use SWI OS_AddCallback.

LDR   R1,Adrplot_Timer0
MOV   R0,#255
STRB   R0,[R1],#1
STR   R1,Adrplot_Timer0

TEQP  R9,#0
MOV   R0,R0

;Should I enable the event again or once is enough ?
;MOV R0,#14        ; Enables an event
;MOV R1,#5         ; PRM 1-145 Interval timer tombe a 0
;SWI "OS_Byte"     ; PRM 1-150

LDMFD R13!,{R0-R12,PC}

.Install_Timer_Routine

You should be pushing at least R14 (the return address) onto the stack
at this point. I can't remember enough about BASIC to tell you whether
you should also be preserving other register values belonging to the
calling environment.

MOV R0,#4         ; PRM 1-413 Write Interval Timer
ADR R1,Counter_Block
SWI "OS_Word"

MOV R0,#&10        ;EventV PRM 1-79
ADR R1,Code_Timer
MOV R2,#0         ;
SWI "OS_Claim"     ; PRM 1-66

;PRM 1-146
; First claim the event then now let's enable it
MOV R0,#14        ; Enables an event
MOV R1,#5         ; PRM 1-145 Interval timer crosses 0
SWI "OS_Byte"     ; PRM 1-150

.Wait_Click_Mouse_Left_Button
SWI "OS_Mouse"   ; PRM 1-699
CMP R2,#4
BNE  Wait_Click_Mouse_Left_Button

The code above doesn't actually wait for a mouse click - it waits for
the mouse button to be depressed, which might be no wait at all if the
button was already held down before running your program. You should
loop whilst waiting for the relevant bit of R2 to change state from 0
to 1 when writing user interaction code like this (typically by using
BIC to clear those bits of the button state that were set last time).

However, it would be simpler and clearer to use SWI OS_Confirm.

BL Remove_Timer_Routine

The line of code above corrupts the value of R14 that you are relying
on to return to the BASIC environment.

MOV   PC,R14

You should certainly be pulling R14 off the stack here. What you have
is an infinite loop (this instruction branches to itself forever).

.Adrplot_Timer0  EQUD 32*1024*1024-480*1024+320*25+160

What makes you so sure that this is the address of the frame buffer?
Why don't you use the API provided? (SWI OS_ReadVduVariables).

--
Christopher Bazley
.



Relevant Pages

  • Re: Sadly, cannot write to 0xB8000
    ...    simple adjust variables according to the input ... write EOI to PIC and return from interrupt. ... MOV AH, AL ... routine to match that of Alex Frounze's Init routine. ...
    (comp.lang.asm.x86)
  • Re: interrupt definition old DOS code, need to find it
    ... XOR     AX,AX ... INT     16 ... routine cleaning the stack. ... MOV BP,SP;2=GET SHIFT STATUS TO AL ...
    (comp.os.msdos.programmer)
  • Re: Newly getting started in C#
    ... In VB I would create the connection to the database and connect to it ... put the connection routine in the program.cs module? ... Scott Roberts    Visa profil ... namespace MyDAL ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Child process does not inherit parents working library
    ... additional BCI Job if the referred JOBD of SBMJOB has ALWMLTTHD, ...     JOB ... parent's (which I have set manually via the CURLIB parameter). ... As a contribution to the group, here is a C++ routine to get the ...
    (comp.sys.ibm.as400.misc)
  • Re: Move Non Zero Columns Left?
    ...   k = 1 ... just testing out the routine. ... Now go back to the Tools menu in your sheet and goto Macro then select ...  You will see the CopyNumbers macro in the list. ...
    (comp.databases.ms-access)