REF: TrackBall Programming Guide
From: Craig Lisowski (aa853@cleveland.Freenet.Edu)
Date: 04/21/94-11:21:57 PM Z
- Next message by date: Michael Current: "UPGRADE: 600XL->64K"
- Previous message by date: Craig Lisowski: "UPGRADE: 1200XL Clearpic--video upgrade"
- Return to Index: Sort by: [ date ] [ author ] [ thread ] [ subject ]
From: aa853@cleveland.Freenet.Edu (Craig Lisowski) Subject: REF: TrackBall Programming Guide Date: Thu Apr 21 23:21:57 1994 PROGRAMMING THE CX-22 TRACK BALL William Bartlett October 26, 1983 This document will attempt to provide programmers with an understanding of what the Atari Trak-Ball is capable of doing, how it does it, and how to tap it's potential from an appli- cation program. The scope of this document is limited to using the Trak-Ball in true trak-ball (TB) mode. Programming the Trak-Ball in joystick (JS) mode is exactly the same as programming a joystick. Let me briefly review how the PIA chip handles the Atari joystick. A joystick plugged into port 1 will toggle the lower four bits of PORTA located at $D300 and shadowed at $278. One bit is cleared (zero) to indicate the joystick is being pushed in any of four directions; right, left, forward or back. If the joystick is stationary, the four bits are set (one). Atari BASIC provides the STICK function to provide the value of these four bits to a BASIC programmer. HOW DOES A TRAK-BALL DIFFER FROM A JOYSTICK? A joystick is only capable of indicating direction whereas a trak-ball is capable of indicating direction and speed. The best implementation of trak-ball application programs will re- flect the varying speeds of ball movement. HOW IS DIRECTION AND SPEED IMPLEMENTED IN THE HARDWARE? A trak-ball plugged into port 1 will toggle the lower four bits of PORTA located at $D300 and shadowed at $278. There are two direction bits and two rate bits; one each for the hori- zontal and vertical axis. The direction bits indicate which direction along the axis the ball is rolling. The rate bits change from 0 to 1 and back to 0 as the ball is rolled. The faster the ball rolls, the faster the rate bits change. HOW CAN AN APPLICATION PROGRAM UTILIZE THE TRAK-BALL? Unfortunately, Atari BASIC is very inefficient for using the Trak-Ball. To quickly implement direction and speed it is necessary to test the individual bits of PORTA. The AND func- tion in Atari BASIC is byte-to-byte instead of a true bit-to-bit test. Therefore, machine language is going to be required to tap the potential of the Trak-Ball. To determine the direction of ball movement, the direction bits need to be tested only once. To determine the speed of ball movement, the rate bits will have to be sampled many times and a count made of the changes from 0 to 1 and back. The lower four bits of PORTA are assigned as follows: +---------------+---+---+---+---+ PORTA >> | | 4 | 3 | 2 | 1 | +---------------+---+---+---+---+ * bit 4 = vertical rate, * bit 3 = vertical direction (0=up, 1=down), * bit 2 = horizontal rate, * bit 1 = horizontal direction (0=left, 1=right). Let's assume we wish to control an object on the screen with a trak-ball. There are two logical approaches to this programming problem. I shall refer to these as the vector approach and the incremental approach. VECTOR : The vector approach is to maintain a value for the horizontal and vertical locations, sample the trak-ball N times, calculate the new horizontal and vertical locations, and then reposition the object. A complication is that if the object is a player or missile, we could vector to a new location without recognizing a collision. Another complication is that of boundaries. What if the new location is outside of a boundary? Should we ignore the boundary, ignore the sample, or calculate where the vector crosses the boundary? Using the vector method we will either have complicated coding or flaky response. INCREMENTAL : The incremental approach is to move the object when the rate bit changes as you sample the trak-ball N times. Boundary and collision checking is much simpler than that of the vector approach. SAMPLE PROGRAMS I have provided three tutorial programs to be used in conjunction with the trak-ball: 1) TBALLTST.BAS allows you to observe the lower four bits of PORTA changing so that you can familiarize yourself with their action. 2) TBALL.BAS will demonstrate how the trak-ball can be sampled from Atari BASIC to provide a signed value of direction and speed for each axis. The three numbers displayed are the horizontal axis, the vertical axis, and the joystick value. 3) VBITBALL.BAS demonstrates a vertical blank routine to sample the trak-ball and move a player using the incremental method discussed above. Because the movement is done using a vertical blank interrupt (background), other activity may proceed in BASIC (foreground). (Listing follows:) 10 REM :TBALLTST.BAS 100 DATA 169,0,133,212,133,213,104,104,104,133,203,104,104 101 DATA 37,203,240,2,230,212,96 110 FOR I=1536 TO 1555:READ J:K=K+J:POKE I,J:NEXT I 111 IF K-2736 THEN ? "BAD DATA!":END 120 GRAPHICS 0:POKE 710,0:TRAP 21:? "BIT OPTIONS (0-15)...";:INPUT OP 125 GRAPHICS 18 130 I=PEEK(632):POSITION 0,0 135 IF USR(1536,OP,8) THEN ? #6;USR(1536,I,8),"Y RATE" 136 IF USR(1536,OP,4) THEN ? #6;USR(1536,I,4),"Y DIR" 137 IF USR(1536,OP,2) THEN ? #6;USR(1536,I,2),"X RATE" 138 IF USR(1536,OP,1) THEN ? #6;USR(1536,I,1),"X DIR" 140 IF PEEK(53279)=6 THEN 120 141 GOTO 130 10 ;#D1:TBALLTST.SRC 20 ;TEST A BIT 00D4 30 BASIC = $D4 00CB 40 MASK = $CB 0000 50 *= $0600 0600 A900 60 LDA #0 0602 85D4 70 STA BASIC 0604 85D5 80 STA BASIC+1 0606 68 90 PLA ;BASIC 0607 68 0100 PLA ;MSB MASK 0608 68 0110 PLA ;LSB MASK 0609 85CB 0120 STA MASK 060B 68 0130 PLA ;MSB VALUE 060C 68 0140 PLA ;LSB VALUE 060D 25CB 0150 AND MASK 060F F002 0160 BEQ DONE 0611 E6D4 0170 INC BASIC 0613 60 0180 DONE RTS 10 REM :TBALL.BAS 100 REM 1536-1619 101 DATA 104,169,0,133,212,133,213,173,0,211,41,2,133,205,160,255,173,0,211 102 DATA 41,2,197,205,240,2,230,212,133,205,136,208,240,173,0,211,41,1,208 103 DATA 6,165,212,9,128,133,212,173,0,211,41,8,133,205,160,255,173,0,211 104 DATA 41,8,197,205,240,2,230,213,133,205,136,208,240,173,0,211,41,4,208 105 DATA 6,165,213,9,128,133,213,96,-1 110 FOR I=1536 TO 1619:READ J:K=K+J:POKE I,J:NEXT I 111 IF K-11306 THEN ? "BAD DATA!":END 200 U=USR(1536):Y=INT(U/256):X=U-Y*256 210 IF X>127 THEN X=X-128:IF X THEN X=-X 211 IF Y>127 THEN Y=Y-128:IF Y THEN Y=-Y 220 ? X,Y,PEEK(632):GOTO 200 10 ;#D1:TBALL.SRC 20 ;SAMPLE TBALL X,Y DIR, RATE 30 ;CALLED FROM BASIC U=USR(ORG) ;HIBYTE=Y AXIS ;LOBYTE=X AXIS D300 40 PORTA = $D300 00D4 50 XCOUNT = $D4 00D5 60 YCOUNT = $D5 00CD 70 LAST = $CD 0000 80 *= $600 0600 68 90 PLA 0601 A900 0100 LDA #0 0603 85D4 0110 STA XCOUNT 0605 85D5 0120 STA YCOUNT 0607 AD00D3 0130 XINIT LDA PORTA 060A 2902 0140 AND #2 060C 85CD 0150 STA LAST 060E AOFF 0160 LDY #$FF 0610 AD00D3 0170 XSAMP LDA PORTA 0613 2902 0180 AND #2 0615 C5CD 0190 CMP LAST 0617 F002 0200 BEQ XDEC 0619 E6D4 0210 INC XCOUNT 061B 85CD 0220 XDEC STA LAST 061D 88 0230 DEY 061E D0F0 0240 BNE XSAMP 0620 AD00D3 0250 LDA PORTA 0623 2901 0260 AND #1 0625 D006 0270 BNE YINIT 0627 A5D4 0280 LDA XCOUNT 0629 0980 0290 ORA #128 062B 85D4 0300 STA XCOUNT 062D AD00D3 0310 YINIT LDA PORTA 0630 2908 0320 AND #8 0632 85CD 0330 STA LAST 0634 A0FF 0340 LDY #$FF 0636 AD00D3 0350 YSAMP LDA PORTA 0639 2908 0360 AND #8 063B C5CD 0370 CMP LAST 063D F002 0380 BEQ YDEC 063F E6D5 0390 INC YCOUNT 0641 85CD 0400 YDEC STA LAST 0643 88 0410 DEY 0644 D0F0 0420 BNE YSAMP 0646 AD00D3 0430 LDA PORTA 0649 2904 0440 AND #4 064B D006 0450 BNE RETURN 064D A5D5 0460 LDA YCOUNT 064F 0980 0470 ORA #128 0651 85D5 0480 STA YCOUNT 0653 60 0490 RETURN RTS 10 REM :VBITBALL.BAS 100 REM 1536-1762 101 DATA 160,255,173,0,211,41,2,133,203,173,0,211,41,2,197,203,240,39,133,203 102 DATA 173,0,211,41,1,240,16,174,149,6,232,224,196,240,22,142,149,6,142,0 103 DATA 208,208,14,174,149,6,202,224,48,240,6,142,149,6,142,0,208,136,208,205 104 DATA 160,255,173,0,211,41,8,133,203,173,0,211,41,8,197,203,240,65,133,203 105 DATA 173,0,211,41,4,208,29,174,150,6,224,32,240,49,202,142,150,6,152,72 106 DATA 160,8,189,1,44,157,0,44,232,136,16,246,104,168,208,27,174,150,6,224 107 DATA 218,240,20,232,142,150,6,152,72,160,8,189,6,44,157,7,44,202,136,16 108 DATA 246,104,168,136,208,179,76,98,228,0,0,104,160,255,169,0,153,0,44,136 109 DATA 208,250,185,219,6,153,120,44,200,192,8,208,245,169,120,141,149,6,141,150 110 DATA 6,141,0,208,169,34,141,192,2,169,1,141,8,208,169,40,141,7,212,169 111 DATA 62,141,47,2,169,3,141,29,208,169,7,162,6,160,0,32,92,228,96,24 112 DATA 24,24,231,231,24,24,24 113 REM * 227 BYTES 120 FOR I=1536 TO 1762:READ J 130 K=K+J:POKE I,J:NEXT I 140 IF K-26973 THEN ? "BAD DATA!":END 150 I=USR(1687) 10 ; :VBITBALL.SRC 20 ; VBLANK TO MOVE PLYR 0 WITH T-BALL 30 ; EQUATES =D300 40 PORTA = $D300 =00CB 50 LASTA = $CB 0000 60 *= $0600 70 ;X-AXIS:BIT1=X DIR, BIT2=X RATE 0600 A0FF 80 VBI LDY #$FF 0602 AD00D3 90 LDA PORTA 0605 2902 0100 AND #2 0607 85CB 0110 STA LASTA 0609 AD00D3 0120 XSAMP LDA PORTA 060C 2902 0130 AND #2 060E C5CB 0140 CMP LASTA 0610 F027 0150 BEQ XNEXT 0612 85CB 0160 STA LASTA 0614 AD00D3 0170 LDA PORTA 0617 2901 0180 AND #1 0619 F010 0190 BEQ XLEFT 061B AE9506 0200 XRGHT LDX XPOS 061E E8 0210 INX 061F E0C4 0220 CPX #196 0621 F016 0230 BEQ XNEXT 0623 8E9506 0240 STX XPOS 0626 8E00D0 0250 STX P0HPOS 0629 D00E 0260 BNE XNEXT 062B AE9506 0270 XLEFT LDX XPOS 062E CA 0280 DEX 062F E030 0290 CPX #48 0631 F006 0300 BEQ XNEXT 0633 8E9506 0310 STX XPOS 0636 8E00D0 0320 STX P0HPOS 0639 88 0330 XNEXT DEY 063A D0CD 0350 ;Y AXIS: BIT3=Y DIR, BIT4=Y RATE 063C A0FF 0360 LDY #$FF 063E AD00D3 0370 LDA PORTA 0641 2908 0380 AND #8 0643 85CB 0390 STA LASTA 0645 AD00D3 0400 YSAMP LDA PORTA 0648 2908 0410 AND #8 064A C5CB 0420 CMP LASTA 064C F041 0430 BEQ YNEXT 064E 85CB 0440 STA LASTA 0650 AD00D3 0450 LDA PORTA 0653 2904 0460 AND #4 0655 D01D 0470 BNE YDOWN 0657 AE9606 0480 YUP LDX YPOS 065A E020 0490 CPX #32 065C F031 0500 BEQ YNEXT 065E CA 0510 DEX 065F 8E9606 0520 STX YPOS 0662 98 0530 TYA 0663 48 0540 PHA 0664 A008 0550 LDA #8 0666 BD012C 0560 YUP1 LDA P0BASE+1,X 0669 9D002C 0570 STA P0BASE,X 066C E8 0580 INX 066D 88 0590 DEY 066E 10F6 0600 BPL YUP1 0670 68 0610 PLA 0671 A8 0620 TAY 0672 D01B 0630 BNE YNEXT 0674 AE9606 0640 YDOWN LDX YPOS 0677 E0DA 0650 CPX #218 0679 F014 0660 BEQ YNEXT 067B E8 0670 INX 067C 8E9606 0680 STX XPOS 067F 98 0690 TYA 0680 48 0700 PHA 0681 A008 0710 LDY #8 0683 BD062C 0720 YDOWN1 LDA P0BASE+6,X 0686 9D072C 0730 STA P0BASE+7,X 0689 CA 0740 DEX 068A 88 0750 DEY 068B 10F6 0760 BPL YDOWN1 068D 68 0770 PLA 068E A8 0780 TAY 068F 88 0790 YNEXT DEY 0690 D0B3 0800 BNE YSAMP 0692 4C62E4 0810 JMP XITVBV 0695 00 0820 XPOS .BYTE 0 0696 00 0830 YPOS .BYTE 0 0840 ;INIT. PM/VBI 0850 ;EQUATES =D407 0860 PMBASE = $D407 =2800 0870 PMRAM = $2800 =2C00 0880 P0BASE = PMRAM+$0400 =D000 0890 P0HPOS = $D000 =02C0 0900 P0COLR = $02C0 =D008 0910 P0SIZE = $D008 =022F 0920 SDMCTL = $022F =D01D 0930 GRACTL = $D01D =0224 0940 VVBLKD = $0224 =E45C 0950 SETVBV = $E45C =E462 0960 XITVBV = $E462 0970 ;CLEAR PLAYER 0 0697 68 0980 PLA 0698 A0FF 0990 LDY #$FF 069A A900 1000 LDA #0 069C 99002C 1010 INIT1 STA P0BASE,Y 069F 88 1020 DEY 06A0 D0FA 1030 BNE INIT1 1040 ;DEFINE PLAYER 0 06A2 B9DB06 1050 INIT2 LDA P0SHAP,Y 06A5 99782C 1060 STA P0BASE+120,Y 06A8 C8 1070 INY 06A9 C008 1080 CPY #8 06AB D0F5 1090 BNE INIT2 06AD A978 1100 LDA #120 06AF 8D9506 1110 STA XPOS 06B2 8D9606 1120 STA YPOS 06B5 8D00D0 1130 STA P0HPOS 06B8 A922 1140 LDA #34 06BA 8DC002 1150 STA P0COLR 06BD A901 1160 LDA #1 ;DOUBLE WIDTH 06BF 8D08D0 1170 STA P0SIZE 06C2 A928 1180 LDA #PMRAM/256 06C4 8D07D4 1190 STA PMBASE 06C7 A93E 1200 LDA #$3E ;SINGLE LINE P/M 06C9 8D2F02 1210 STA SDMCTL 06CC A903 1220 LDA #$03 ;TURN ON P/M 06CE 8D1DD0 1230 STA GRACTL 1240 ;INIT. VBI 06D1 A907 1250 LDA #7 06D3 A206 1260 LDX #VBI/256 06D5 A000 1270 LDY #VBI&255 06D7 205CE4 1280 JSR SETVBV 06DA 60 1290 RTS 06DB 181818E7 1300 P0SHAP .BYTE $18,$18,$18,$E7,$E7,$18,$18,$18 06DF E7181818 [END]
- Next message by date: Michael Current: "UPGRADE: 600XL->64K"
- Previous message by date: Craig Lisowski: "UPGRADE: 1200XL Clearpic--video upgrade"
----------------------------------------- Return to message index