General Information
Author: John Maris (prepared by Mathy v. Nisselroy)
Assembler: Mac65
Published: MegaMagazine 7
Download: http://www.mathyvannisselroy.nl/special%20stuff.htm
PDF: MOUSE ROUTINE IN AN INTERRUPT/mouse.pdf
OK, here is the text that accompanied the mouse routine I posted on alt.binaries.atari. Unfortunately the original file was self extracting. So I had to print it out and type it back in. I hope somebody will read the stuff below and use it in his or her own program. The text and code where written for the Atari 8 bit, but the idea should work on other computers too.
[number] means that there is a small explanation for those not living in the Atari 8 bit world at the bottom of the text.
Mathy van Nisselroy
By The Missing Link [1]
In the last years the mouse became very popular, even on Atari 8-bit machines. I've seen a lot of routines, but none of them were working very good. They took almost all processor time in the main loop or they were very slow, etc. I talked to your editor [2] very often about this subject and we were both working on a better routine. I decided to put my mouse routine into a Pokey [3] Timer Interrupt....
A few month ago while I was shopping, I got the great idea. Finally I knew how to do it. I went home, started MAC65 [4], typed some lines in 10 minutes, and the routine worked great!
The first routine worked in a DLI [5] and VBI [6]. So I knew that it was possible to put a mouse routine in such an interrupt. I could even load from disk or play some samples while I was playing with the mouse. A few days later Freddy [2] visited me and he was amazed. I showed him my routine and he was surprised because of the length and the frequency. The routine was short, very fast and worked very good. You should have seen his face when I was playing a mouse, while the computer loaded the directory into the machine....
Later I told to some other programmers about this routine and now we can see a lot of mouse routines which work in an interrupt. Most of these routines are still slow or you get a 'flying' cursor. If you move the mouse too fast, the cursor will move in reversed direction or will even NOT move. After I had seen these 'f**king' routines I decided to publish my routine on Mega Magazine [7] with some documentation, so everybody can use a better mouse routine. I've called it the 'TML Mouse Routine'. The routine is public domain, but it would be nice if you let me know (or MegaZine [7]) if you use the routine in one of your products. It would be nicer if you mention the creator in your programs....
Depending on the mouse (ST or AMIGA) you will get 4 numbers if you move the mouse horizontal and 4 other numbers for the vertical direction. For example: Move the mouse from left to right and you will get the numbers (STICK(0 or 1) [8] ) 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 etc. (these aren't the right numbers, but it is only an example). If you read stick(0) twice, you have two numbers and will know in what direction the mouse moved... If you get a 1 and a 2, the mouse was moved to the right and if you get a 2 and a 1, the mouse was moved to the left. You can do the same thing for the vertical direction.
Now you can create a very big routine with compares, etc., but that will take a lot of time and you have to check the stick very often (Freddy did such a routine in the main loop and there was no time left for any other action), I have made a interrupt routine which checked the mouse 800 times in a second. This routine worked like all routines, get a new value from the mouse, compare it to the old value and do some action. This routine was also large and didn't work very good. The trick is the use of an 'action table'. Get the old value shift it to the left two times and add the new value. Now you will have a unique value between 0 and 15. Use this value as index for the table.
An example:
Old value = 2 (shifted 2x makes 8)
New value = 1 (add to 8)
Index value = 9
Earlier I wrote that a 2 and a 1 was a movement to the left, so we have to decrease the X-pointer. Position 9 will be a 255 in the index tabel.
Old value = 1 (shifted 2x makes 4)
New value = 2 (add to 4)
Index value = 6
Numbers 1 and 2 is a movement to the right, we have to increase the X-pointer. We have to put on the sixth position in the index table a 1.
Conclusion: Now we have only to shift the old value 2 times, add the new value, use it as index, and add the value we've got to the X-position. We can do the same for the Y-position. This is a very fast routine which takes just some time. But still, this is not the final one....
Sometimes you will get the same value. (old = 1 and new = 1) This means that there was no mouse action or a very very fast action in unknown direction. Do nothing, so put 0 in your index table on position (1+4=5).
The same for 1 and 3. Of course, there must have been some action, but you can't know what kind of action. It is two steps if the mouse is moved to the right, but also two steps if the mouse was moved to the left. So no action on (3+4=7) in your index table.
The last part was the most important part of this textfile. If you don't know what kind of action there was, even if you are sure that there was some action, do nothing! If you do anything you will get a reversed mouse or a 'flying' one.
On the backside of this disk you will find a pre-screen of my new texteditor. You can play with it, open some windows, etc., but that's all. Just an example. You can also find the mouse-source on this disk. It's in MAC65 [4] format. This one is public domain. Use it have a lot of fun, as long as you remember that you took it from this great magazine [7] and remember who wrote the routine. See you next time!
[#1] John Maris, founder of A.N.G.
[#2] Freddy Offenga, editor of [7]
[#3] Sound chip of the Atari 8bit computer
[#4] MAC65: Assembler software
[#5] DLI: small piece of software that tells the graphics co-processor (ANTIC) in the Atari 8 bit what to do
[#6] VBI: Vertical Blank Interrupt.
[#7] Mega Magazine or just MegaZine: A disk magazine for the Atari 8 bit computer. Seven issues appeared, then they stopped.
[#8] STICK (0) or STICK (1): an Atari BASIC command used to read joystick ports pins 1 through 4.
For those who wanna look at the code, the PIA, which controls the joysticks in the Atari, is placed at $D300-$D303. Should the source use a different address between $D300 and $D3FF, just substract 4 off this number untill you get in the above mentioned range. BTW apart from the occasional SPACE and capital, I changed nothing about this text.
1000 ;MOUSE ROUTINE IN A DLI 1010 ; MAKE YOUR OWN DL WITH 1020 ;INTERUPT ENABLE, ETC. 1030 ;OR YSE THE INTERUPT IN 1040 ;POKEY TIME INTERUPT! 1050 ; 1060 ;PUBLIC DOMAIN 1994 1070 ;PUBLISHED ON MEGAMAGAZINE 1080 ; POKEY MAGZINE 1090 ; THE BEST OF... 1100 ; 1110 ;WRITTEN BY THE MISSING LINK 1120 ; 1130 ;OLDX = OLD X-VALUE MOUSE 1140 ;OLDY = OLD Y-VALUE MOUSE 1150 ;MXAS = X POSITION FOR CURSOR 1160 ;MMAXX=MAXIMUM X-SCREEN-POS 1170 ;MMAXY=MAXIMUM Y-SCREEN-POS 1180 ;MMINX=MINIMUM X-SCREEN-POS 1190 ;MMINY=MINIMUM Y-SCREEN-POS 1191 ; 1200 ;SET INTERRUPTPOINTER 1210 LDA # <MOUSE 1220 STA 512 1230 LDA # >MOUSE 1240 STA 513 1250 ;INIT MOUSE ROUTINE 1260 JSR MOUSEON 1270 ;INIT VBI ROUTINE FOR CURSOR 1280 LDA #6 1290 LDX # >VBI 1300 LDY # <VBI 1310 JSR $E45C 1320 ;ENDLESS LOOP 1330 DO JMP DO 1340 ; 1350 ; 1360 ;THE MOUSEROUTINE 1370 MOUSE 1380 PHA 1390 TXA 1400 PHA 1410 TYA 1420 PHA 1430 MOUSEA 1440 LDA $D300 ; 1450 LSR A ;MOUSE ON 1460 LSR A ;PORT 1 1470 LSR A ; 1480 LSR A ; 1490 PHA ;SAVE VALUE 1500 AND #3 ;GET X-VALUE 1510 ORA OLDX ; 1520 TAX ; 1530 AND #3 ;MAKE X-INDEX 1540 ASL A ; 1550 ASL A ; 1560 STA OLDX ;SAVE AS OLD 1570 LDY MXAS ; 1580 LDA MOUSETAB,X ;GET TABLE 1590 BMI MOUSY ;ACTION? NO! 1600 BNE MOUSE1 ;YES! DECREASE 1610 MOUSE0 1620 INY ;INCREASE 1630 CPY MMAXX ;MAXIMUM XAS? 1640 BCC MOUSY ;NO, EXIT 1650 MOUSE1 1660 DEY ;DECREASE 1670 CPY MMINX ;MINIMUM XAS? 1680 BCC MOUSE0 ;YES! INCREASE 1690 MOUSY 1700 STY MXAS ;STORE XPOINTER 1710 PLA ;GET MOUSEVALUE 1720 LSR A 1730 LSR A ;SEE THE ROUTINE 1740 AND #3 ;ON THE XAS. IT 1750 ORA OLDY ;IS THE SAME! 1760 TAX 1770 AND #3 1780 ASL A 1790 ASL A 1800 STA OLDY 1810 LDY MYAS 1820 LDA MOUSETAB,X 1830 BMI MOUSEX 1840 BNE MOUSE2 1850 MOUSE1.1 1860 INY 1870 JMP MOUSE3 1880 MOUSE2 1890 DEY 1900 MOUSE3 1910 CPY MMINY 1920 BCC MOUSE1.1 1930 CPY MMAXY 1940 BCS MOUSE2 1950 MOUSEX ; END OF 1960 STY MYAS ;Y-ROUTINE 1970 PLA ;RESTORE 1980 TAY ;A, X & Y 1990 PLA 2000 TAX 2010 PLA 2020 RTI 2030 ; 2040 ;THE Indextable 0=no action 2050 MOUSETAB 2060 .BYTE 255,1,0,255,0,255,255,1,1,255,255,0,255,0,1,255 2070 ; 2080 ;ENABLE DLI 2090 MOUSEON 2100 LDA #192 2110 STA $D40E 2120 RTS 2130 ;DISABLE DLI 2140 MOUSEOFF 2150 LDA #64 2160 STA $D40E 2170 RTS 2180 ; 2190 VBI 2200 ;PUT CURSOR ON SCREEN... 2210 JMP $E45F 2220 ; 2230 ;