View Full Version : Interupt e.g. on 68HC11
MLCarter
08-17-00, 03:04 AM
With some help from Rob I got the free running timer interupt to increment a counter<br>as follows ;<p>HEX<br>: IS CONSTANT ;<p>B025 IS TFLG2<br>B024 IS TMSK2<br>1004 IS CNT<br>1002 IS INC<p>0 CNT !<br>1 INC !<p>CODE SIR-TIME<br>(B6 C, 80 , LDAA #80 load A ext)<br>86 C, 80 C, ( correction LDDA # 80 )<br>B7 C, TFLG2 , ( STAA TFLG2 store A ext)<br>FC C, INC , ( LDD INC load double accumulator ext)<br>F3 C, CNT , ( ADDD CNT add double ext)<br>FD C, CNT , ( STD CNT store double accumulator ext)<br>3B C, ( RTI return from interupt)<br>END-CODE<p>CODE-SUB +INT 0E C, 39 C, END-CODE<br>CODE-SUB -INT 0F C, 39 C, END-CODE<p>: ON -INT ['] SIR-TIME @ 100 /MOD<br>7E B7CB EEC!<br> B7CC EEC!<br> B7CD EEC!<br>80 TMSK2 C!<br>+INT ;<p>DECIMAL<br>0 4102 !<br>0 4104 !<br>0 4106 !<br>100 4152 !<p>: TIMEUP CNT @ 1831 > IF CNT @ 1831 - CNT ! 4102 1+! 4102 @ . CR THEN<br> 4102 @ 59 > IF 4102 @ 60 - 4102 ! 4104 1+! THEN<br> 4104 @ 23 > IF 0 4104 ! 4106 1+! CNT @ 4152 @ - CNT ! THEN ;<br>( accumulate minutes,hours,days and adjust at the end of the day ) <p>: TEST ON ." PRESS ANY KEY TO END " CR<br> BEGIN<br> TIMEUP<br> ?TERMINAL UNTIL<br>." End " CR ABORT ;<br> <p>
Please forgive the digression. In what dialect of NMI Forth for the 68HC11 is 'IS' a valid word?<p>What is at $8000 that is to be loaded? As far as I know, that's RAM.<p>Jerry<p>----------<br>Engineering is the art of making what you want from things you can get.<p><br>
MLCarter
08-19-00, 12:38 AM
I just use "IS" to save typing constant each time. Its not part of Forth 3.5 that I'm using.<br>Are you referring to the first assembler load with (B6)? I know this should be (86) LDAA immediate but this would lock the thing up. Change it to (B6) and for some reason it runs. Note I'm no assembler expert!
First of all, when one programs in assembler, more care must be taken. <br> When the assembler opcode generation is also part of the program, then one<br> must walk very carefully indeed.<p> LDAA 80 ( as you have coded with B6 C, 80 , <p> This loads a byte value into accumulator A from memory location 80<br> which happens to be in the middle of PAD, the number conversion<br> buffer for formatted output. Not a good place to get constant<br> values. By luck you'd get the highest bit set of the byte and<br> that would work, but sometimes you'd get the bit cleared because<br> of an artifact of some number output and it wouldn't work. Worst<br> case of all, an elusive bug.<p> The required code is:<p> LDAA # 80 ( which should be encoded with 86 C, 80 C,<p> As you mentioned the 86 opcode caused a crash always. This was<br> because the 80 value needed to be layed down as a byte with C,<br> not just , which would put 0 in the A accumulator and then the<br> 80 would be interpreted as SUBA # whatever the next opcode was<br> and boom. In the above correct code, it is two bytes.<p> Rob
Off topic? A note to M.L.Carter:<p>I almost wrote that you probably wanted immediate mode and C, , based on what I understood of the code and your use of '#'. I didn't, because I've too often made myself look foolish by telling others what they want. The code you posted had, for practical purposes, no comments, and I didn't bother to work out the logic.<p>I can just hear: "No comments? Every line is commented!" True, but there's no information there. I know perfectly well what the ops do; an informative comment would tell why you used the ones you did. To put it differently: the code itself tells a reader what you are doing; the comments should say why you are doing it. Other good comments are the assumptions and requirements that the constrain the code, even when the constraint isn't embodied in a single op. <p>Good luck, and keep up the good work.<p>Jerry<p>----------<br>Engineering is the art of making what you want from things you can get.<br>
As a postscript to this discussion, if you want a very simple way of just executing a Forth word every 100 ms, without interrupts or assembler, try this:<p>( Simple 100 ms task executer Rob Chapman Aug 24, 2000 )<p>( ==== Simple task for incrementing a counter ==== )<br> VARIABLE count<p>: C++ count 1+! ;<br>: C. count @ U. ;<p>HEX<br>( ==== 100 ms task master ==== )<br>B00E CONSTANT TCNT ( free running counter that increments every 500ns )<p>DECIMAL<br>: EVERY-100MS ( -- ) ( execute a task every 100 ms )<br> 0 count ! C.<br> TCNT @ ( use free running counter to mark time )<br> BEGIN ( loop until keyboard hit )<br> 4 0 ( count 4 periods of 25 ms: 50000 * 500 ns )<br> DO BEGIN TCNT @ OVER - 50000 U< 0= UNTIL 50000 + LOOP<br> C++ ( put your word here instead of C++ )<br> ?TERMINAL ( check for keyboard input )<br> UNTIL DROP C. ;<p><br> Rob<br>
vBulletin v3.0.7, Copyright ©2000-2012, Jelsoft Enterprises Ltd.