;ÁÃÍÅ 0.07 ; --- ÃONFIGURABLE VALUES ; ÓTART ADDRESS *=$C000; Ã64 VALUE ;*=$0C00; Ã128 VALUE ; ÏUTPUT FILE NAME !TO "INPUTDRV64.BIN"; Ã64 FILE NAME ;!TO "INPUTDRV128.BIN"; Ã128 FILE NAME ; ÐOINTER'S MAXIMUM COORDINATES ÍAXIMUMÃOORDINATEØ = 319; ÖÉÃ VALUE ;ÍAXIMUMÃOORDINATEØ = 639; ÖÄÃ VALUE ÍAXIMUMÃOORDINATEÙ = 199 ; ÍAXIMUM STEP SIZE ("SPEED") FOR ; JOYSTICK ACCELERATION ROUTINE, IN ; PIXELS. ÍAXÓTEP = $10; (MAX. $7F) ; ÄISTANCE BEFORE ACCELERATION STARTS, ; IN PIXELS. ÍAXÔIME = $04; (MAX. $7F) ; ÓPRITES TO USE FOR OVERLAY POINTER ÓPRITE_Á = 0 ÓPRITE_Â = 1 ; ÃOORDINATES OF "POINTER PIXEL" WITHIN ; POINTER SPRITES; ADJUST THESE IF YOU ; USE DIFFERENT SPRITES. ; (0,0) IS SPRITE'S UPPER LEFT PIXEL. ÓPRITE_ÈOTSPOTØ = 1 ÓPRITE_ÈOTSPOTÙ = 1 ; ÂASE OF ÖÉÃ REGISTERS TO WRITE TO. ÖÉÃ_ÂASE = $D000; Ã64 VALUE ;ÖÉÃ_ÂASE = $11D6; Ã128 VALUE, LOCATION ; OF MIRROR REGISTERS. ; ÌOCATIONS TO STORE BUTTON STATES, ; $FF = PRESSED, $00 = NOT PRESSED. ; ÍOUSE USES BOTH BUTTONS, JOYSTICK ; ONLY USES "ÌEFTÂUTTON". ÌEFTÂUTTON = $A4; Ã64 VALUE ÒIGHTÂUTTON = $A5; Ã64 VALUE ;ÌEFTÂUTTON = $FA; Ã128 VALUE ;ÒIGHTÂUTTON = $FF; Ã128 VALUE ; ÌOCATION TO STORE POINTER'S CURRENT ; PIXEL COORDINATES. ÔHE DRIVER CODE ; RELIES ON HAVING *FOUR CONSECUTIVE* ; BYTES: ; X LOW, X HIGH, Y LOW, Y HIGH. ÃOORDINATES = $FB; $FB-$FE ; ÌOCATION TO STORE POINTER'S CURRENT ; CHARACTER COORDINATES. ÃHARØ = $B3; Ã64 VALUE ÃHARÙ = $B4; Ã64 VALUE ;ÃHARØ = $9B; Ã128 VALUE ;ÃHARÙ = $9C; Ã128 VALUE ; --- ÓYSTEM CONSTANTS ; ÉNTERRUPT VECTOR SYS_IIRQ = $0314 ; É/Ï REGISTERS SID_POT = $D419 CIA1_PRA = $DC00 CIA1_PRB = $DC01 CIA1_DDRB = $DC03 ;MMU_CR = $FF00; Ã128 ONLY ; --- ÌABEL DEFINITIONS ; ÎEW NAMES FOR SOME PRECALCULATED ; VALUES, ONLY TO IMPROVE READABILITY. ; ÄON'T CHANGE THESE. ÐOINTERØNOW = ÃOORDINATES ÐOINTERÙNOW = ÃOORDINATES+2 ÓPRITEÁ_Ø = ÖÉÃ_ÂASE+2*ÓPRITE_Á ÓPRITEÁ_Ù = ÖÉÃ_ÂASE+2*ÓPRITE_Á+1 ÓPRITEÂ_Ø = ÖÉÃ_ÂASE+2*ÓPRITE_Â ÓPRITEÂ_Ù = ÖÉÃ_ÂASE+2*ÓPRITE_Â+1 ÓPRITES_ÏÆ = ÖÉÃ_ÂASE+16; Ø ÏVERFLOW ; ÔHE CHARACTER "^" IN THE FOLLOWING ; CALCULATION MEANS "TO THE POWER OF". ; ÉT IS ÁÃÍÅ SYNTAX - IF YOUR ASSEMBLER ; CANNOT DO THIS, YOU MAY WANT TO USE ; HARDCODED VALUES HERE INSTEAD OF ; CALCULATIONS. ÓPRITES_ÂITMASK = 2^ÓPRITE_Á+2^ÓPRITE_Â ÓPRITEÏFFSET_Ø = $18-ÓPRITE_ÈOTSPOTØ ÓPRITEÏFFSET_Ù = $32-ÓPRITE_ÈOTSPOTÙ ; ÉN THE SPRITE COORDINATE SYSTEM, THE ; GRAPHICS PIXEL (0,0) HAS THE ; COORDINATES ($18,$32), SO THESE ARE ; NEEDED FOR CONVERTING. ÂLAME THE ÖÉÃ. ; --- ÅNTRY POINT ; ÂECAUSE THIS ROUTINE IS THE FIRST, ; THE FILE CAN BE ÂÏÏÔED ON A Ã128. ÉNIT ; ÉNITIALISATION CODE, INSTALLS DRIVER ; ON ÉÒÑ VECTOR. ; ÆETCH ÉÒÑ VECTOR AND WRITE TO END LDA SYS_IIRQ LDX SYS_IIRQ+1 STA MOD16+1 STX MOD16+2 ; ÌET ÉÒÑ VECTOR POINT TO DRIVER CODE LDA #<ÅNTRY LDX #>ÅNTRY PHP SEI STA SYS_IIRQ STX SYS_IIRQ+1 PLP ; ÔHE FOLLOWING FIVE COMMANDS ARE ONLY ; NEEDED ON THE Ã128. ; LDA MMU_CR ; TAY ; AND #$FE; ACTIVATE É/Ï CHIPS ; STA MMU_CR ; ÉNIT MOUSE BUTTONS LDA #$11 STA CIA1_PRB ; STY MMU_CR; Ã128 ONLY ; ÔHE FOLLOWING THREE MINI-ROUTINES ARE ; ONLY NEEDED ON THE Ã64. ; ÃOPY SPRITES TO TAPE BUFFER LDX #127 ÃPÌP LDA ÓPRITES,X STA $0340,X DEX BPL ÃPÌP LDA #ÓPRITES_ÂITMASK ; ÓET SPRITE BLOCK POINTERS LDX #$0D STX 2040+ÓPRITE_Á INX STX 2040+ÓPRITE_Â ; ÁCTIVATE POINTER SPRITES ORA ÖÉÃ_ÂASE+21 STA ÖÉÃ_ÂASE+21 ; ÆROM HERE ON, BOTH Ã64+Ã128 AGAIN. :) RTS ; --- ÖARIABLES ; ÐIXEL COUNTER BEFORE ACCELERATING ÊOY×AITTIME !BYTE 0 ; --- ÍAIN CODE ÅNTRY ; ÔHE DRIVER CONSISTS OF SEVERAL ; DISTINCT PARTS. ÔO MINIMISE ; PERFORMANCE WASTAGE, YOU SHOULD ; REMOVE ALL PARTS YOU DON'T NEED FOR ; THE SPECIFIC APPLICATION. ; --- ÐART 0, INITIALISATIONS ; ÍAKE SURE DECIMAL MODE IS OFF CLD ; ÓET BUTTON STATES TO "NOT PRESSED", ; SO THE OTHER PARTS ONLY HAVE TO DEAL ; WITH SETTING THEM TO "PRESSED". LDA #$00 STA ÌEFTÂUTTON STA ÒIGHTÂUTTON ; --- ÐART 1, HANDLING MOUSE MOVEMENTS ; MOUSE X LDX #$00; 0 MEANS "X STUFF" JSR ÐOTÄELTA ; ÎOW SIGNED X MOVEMENT IS IN Á/Ù. ; ÁDD TO CURRENT X VALUE. CLC ADC ÐOINTERØNOW STA ÐOINTERØNOW TYA ADC ÐOINTERØNOW+1 STA ÐOINTERØNOW+1 ; MOUSE Y LDX #$01; 1 MEANS "Y STUFF" JSR ÐOTÄELTA ; ÎOW SIGNED Y MOVEMENT IS IN Á/Ù. ; ÍOUSE AND COMPUTER USE DIFFERENT Y ; DIRECTIONS, SO DON'T ADD TO, BUT ; SUBTRACT FROM CURRENT Y VALUE. ; ÔHIS IS A REVERSE SUBTRACTION - IT ; MIGHT BE HARDER TO UNDERSTAND, BUT IT ; IS FASTER AND SMALLER THAN THE USUAL ; WAY. CLC SBC ÐOINTERÙNOW EOR #$FF STA ÐOINTERÙNOW TYA SBC ÐOINTERÙNOW+1 EOR #$FF STA ÐOINTERÙNOW+1 ; --- ÐART 2, HANDLING MOUSE BUTTONS ; ÐREPARE ÃÉÁ BY SETTING BITS TO INPUT LDY #$11 STY CIA1_DDRB LDX #$FF; $FF MEANS "PRESSED" LDA #$10; CHECK LEFT BUTTON BIT CIA1_PRB BNE ÎOTÌÂ STX ÌEFTÂUTTON; STORE STATE ÎOTÌÂ LDA #$01; CHECK RIGHT BUTTON BIT CIA1_PRB BNE ÎOTÒÂ STX ÒIGHTÂUTTON; STORE STATE ; ÒESET ÃÉÁ TO NORMAL STATE ÎOTÒÂ LDY #$00 STY CIA1_DDRB ; --- ÐART 3, HANDLING THE JOYSTICK ; ÆETCH BYTE HOLDING DIRECTION FLAGS LDA CIA1_PRA TAX; ...AND REMEMBER IT ; ÃHECK 'UP' DIRECTION ROR BCS DOWN ; ÓUBTRACT CURRENT STEP SIZE FROM Y ; VALUE IF NEEDED. TAY SEC LDA ÐOINTERÙNOW SBC ÊOYÓTEPSIZE STA ÐOINTERÙNOW BCS FIXÈIÕP DEC ÐOINTERÙNOW+1 FIXÈIÕP TYA ; ÃHECK 'DOWN' DIRECTION DOWN ROR BCS LEFT ; ÁDD CURRENT STEP SIZE TO Y VALUE IF ; NEEDED. TAY ;CLC; Ã IS ALWAYS CLEAR HERE LDA ÐOINTERÙNOW ADC ÊOYÓTEPSIZE STA ÐOINTERÙNOW BCC FIXÈIÄOWN INC ÐOINTERÙNOW+1 FIXÈIÄOWN TYA ; ÃHECK 'LEFT' DIRECTION LEFT ROR BCS RIGHT ; ÓUBTRACT CURRENT STEP SIZE FROM X ; VALUE IF NEEDED. TAY SEC LDA ÐOINTERØNOW SBC ÊOYÓTEPSIZE STA ÐOINTERØNOW BCS FIXÈIÌEFT DEC ÐOINTERØNOW+1 FIXÈIÌEFT TYA ; ÃHECK 'RIGHT' DIRECTION RIGHT ROR BCS ÐART3ÅND ; ÁDD CURRENT STEP SIZE TO X VALUE IF ; NEEDED. TAY ;CLC; Ã IS ALWAYS CLEAR HERE LDA ÐOINTERØNOW ADC ÊOYÓTEPSIZE STA ÐOINTERØNOW BCC FIXÈIÒIGHT INC ÐOINTERØNOW+1 FIXÈIÒIGHT TYA ÐART3ÅND ; --- ÐART 4, HANDLING JOYSTICK BUTTON ROR BCS ÐART4ÅND LDA #$FF; $FF MEANS "PRESSED" STA ÌEFTÂUTTON ÐART4ÅND ; --- ÐART 5, JOYSTICK ACCELERATION ; ÒESTORE JOYSTICK DIRECTION BITS AND ; CHECK WHETHER TO SET SPEED TO ZERO. TXA AND #$0F; ÃLEAR UNNEEDED BITS CMP #$0F; ÁNY DIRECTION BIT ? BNE INCTEMPO ; ÎO DIRECTION WAS USED, SO RESET SPEED ; AND WAIT COUNTER TO NORMAL. LDA #$01 STA ÊOYÓTEPSIZE LDA #ÍAXÔIME STA ÊOY×AITTIME JMP ÐART5ÅND INCTEMPO ; Á DIRECTION BIT WAS USED, SO CHECK ; WHETHER TO ACCELERATE: ÉF SPEED IS ; ALREADY MAXIMUM SPEED, DON'T ; ACCELERATE. ÊOYÓTEPSIZE=*+1 LDA #$00; (SELF-MODIFYING) ; ÉF THE VARIABLE "ÊOYÓTEPSIZE" WOULD ; HAVE BEEN DEFINED AS A SEPARATE ; LOCATION (USING "!BYTE"), IT WOULD ; HAVE TAKEN A BYTE OF MEMORY. ÂY ; STORING THE VALUE INSIDE AN ÌÄÁ ; COMMAND'S ARGUMENT, WE SAVE THAT ONE ; BYTE. ÉT MIGHT MAKE A DIFFERENCE. :) CMP #ÍAXÓTEP; ÉF SPEED IS MAX., BCS ÐART5ÅND; DON'T ACCELERATE. ; ÓPEED ISN'T MAXIMUM YET. ÃHECK ; WHETHER WE HAVE TO WAIT BEFORE ; ACCELERATING. DEC ÊOY×AITTIME BPL ÐART5ÅND ; ÃOUNTER HAS UNDERRUN, SO ACCELERATE. INC ÊOY×AITTIME; RESET COUNTER INC ÊOYÓTEPSIZE; INCREASE SPEED ÐART5ÅND ; --- ÐART 6, RESTRICT COORDINATE RANGE ; RESTRICT X VALUE LDX #$00; 0 MEANS "X STUFF" JSR ÒESTRICT ; RESTRICT Y VALUE LDX #$02; 2 MEANS "Y STUFF" JSR ÒESTRICT ; --- ÐART 7, POSITIONING SPRITES ; ÓET SPRITES' X POSITIONS LDA ÐOINTERØNOW CLC ADC #ÓPRITEÏFFSET_Ø STA ÓPRITEÁ_Ø; SET BOTH SPRITES STA ÓPRITEÂ_Ø LDA ÓPRITES_ÏÆ; GET X OVERFLOW BCS ÓETÏÆ LDX ÐOINTERØNOW+1 BNE ÓETÏÆ AND #ÓPRITES_ÂITMASK ÅÏÒ $FF BCC ÓTOREÏÆ; Ã IS CLEAR HERE ÓETÏÆ ORA #ÓPRITES_ÂITMASK ÓTOREÏÆ STA ÓPRITES_ÏÆ; SET X OVERFLOW ; ÓET SPRITES' Y POSITIONS LDA ÐOINTERÙNOW CLC ADC #ÓPRITEÏFFSET_Ù STA ÓPRITEÁ_Ù STA ÓPRITEÂ_Ù ; ÔHE Y VALUE'S HIGH BYTE IS USELESS IN ; THIS CASE. ; --- ÐART 8, MAKING CHAR COORDINATES ; ÃONVERT X COORDINATE. ÔHERE ARE ; DIFFERENT "BEST" ROUTINES FOR ; DIFFERENT RESOLUTIONS, SO É'VE GIVEN ; THE ÖÉÃ AND ÖÄÃ ROUTINES. LDA ÐOINTERØNOW LSR LSR LSR LDX ÐOINTERØNOW+1 BEQ ÓETÃØ; ÖÉÃ ONLY ORA #$20; ÖÉÃ ONLY ; ORA ÏRÔABLE,X; ÖÄÃ ONLY ÓETÃØ STA ÃHARØ ; ÃONVERT Y COORDINATE. LDA ÐOINTERÙNOW LSR LSR LSR STA ÃHARÙ ; --- ÁDD FURTHER PARTS HERE ; ÈERE YOU CAN ADD FURTHER ROUTINES, ; FOR EXAMPLE TO USE THE BUTTON STATES ; TO FAKE KEYPRESSES ETC. ; --- ÔHE END ; ÔHE INITIALISATION ROUTINE SETS THE ; ARGUMENT TO THE ADDRESS OF THE ; PREVIOUS ÉÒÑ ROUTINE. MOD16 JMP $FFFF; (SELF-MODIFYING) ; ÔHIS TABLE IS FOR PART 8. ;ÏRÔABLE !BYTE 0,32,64; ÖÄÃ ONLY ; --- "ÒESTRICT" SUBROUTINE ÐOINTERØMAX !WORD ÍAXIMUMÃOORDINATEØ ÐOINTERÙMAX !WORD ÍAXIMUMÃOORDINATEÙ ; "Y" WORD MUST FOLLOW DIRECTLY AFTER ; "X" WORD IN MEMORY. ÒESTRICT ; ÒESTRICT INTERNAL COORDINATES TO ; CONFIGURED RANGE. ÅNTRY CONDITIONS: ; Ø IS DIRECTION HANDLE (0 = X, 2 = Y) LDA ÐOINTERØNOW+1,X BMI ÓETÔO0 CMP ÐOINTERØMAX+1,X BCC ÅOSR BNE ÒESETÃO LDA ÐOINTERØMAX,X CMP ÐOINTERØNOW,X BCS ÅOSR ÒESETÃO LDA ÐOINTERØMAX,X LDY ÐOINTERØMAX+1,X JMP ÄEFÃO ÓETÔO0 LDA #0 TAY ÄEFÃO STA ÐOINTERØNOW,X STY ÐOINTERØNOW+1,X ÅOSR RTS ; --- "ÐOT" SUBROUTINE ; ÔHIS ROUTINE COMPUTES THE MOUSE ; MOVEMENTS AND THEREFORE CONTAINS THE ; SELF-CALIBRATION STUFF AND THE OTHER ; IMPROVEMENTS OVER THE STANDARD 1351 ; DRIVER. ÐOTÍAX !WORD 0; MAX. ÐÏÔS YET PLUS 1 ! ÐOTÍIN !WORD $FFFF; LOWEST ÐÏÔS YET ÐOTÏLD !WORD 0; OLD VALUES ÐOT×IDTH !WORD 0; INTERVAL WIDTH ÈALFÐOT×IDTH !WORD 0; HALF WIDTH ; (BUFFERED FOR SPEED INCREASE) ; ÔHE ABOVE VARIABLES ARE NOT REALLY ; WORDS: ÔHE FIRST BYTE IS THE X VALUE, ; THE SECOND BYTE IS THE Y VALUE ; RESPECTIVELY. ÐOTÄELTA ; ÃOMPUTE THE SIGNED DISTANCE OF MOUSE ; MOVEMENT. ÅNTRY CONDITIONS: ; Ø IS DIRECTION HANDLE (0 = X, 1 = Y) ; ÅXIT CONDITIONS: ; Á/Ù ARE SIGNED DISTANCE (LOW/HIGH) ; ÆIRST, GET NEW VALUE AND CLEAR ; "RECALCULATE SIGNAL WIDTH" FLAG. LDA SID_POT,X LDY #$00 ; ÃHECK WHETHER NEW VALUE IS LOWER THAN ; LOWEST KNOWN. CMP ÐOTÍIN,X BCS M0 ; ÓTORE NEW "LOWEST" UND SET ; "RECALCULATE SIGNAL WIDTH" FLAG. STA ÐOTÍIN,X LDY #$FF ; ÃHECK WHETHER NEW VALUE IS HIGHER ; THAN HIGHEST KNOWN. M0 CMP ÐOTÍAX,X BCC M1 ; ÓET "RECALCULATE SIGNAL WIDTH" FLAG ; AND STORE NEW "HIGHEST". LDY #$FF PHA; ÒEMEMBER CURRENT VALUE ADC #$00; ÁDD ONE (Ã IS SET) STA ÐOTÍAX,X ; ÖALUE $FF (0 AFTER ADDING) MEANS THAT ; THERE IS NO MOUSE CONNECTED, SO RESET ; MIN/MAX IN THAT CASE. BEQ ÒESETÍÍ; ÓTACK IS UNTIDY... PLA; ÒESTORE CURRENT VALUE ; ÉF FLAG IS SET, RECALCULATE SIGNAL ; WIDTH. M1 INY; ÃHECK FLAG BNE M3 TAY; ÂUFFER CURRENT VALUE. LDA ÐOTÍAX,X; ÇET HIGHEST+1 SEC; ÓUBTRACT LOWEST SBC ÐOTÍIN,X BCC M2 STA ÐOT×IDTH,X; ÓTORE SIGNAL LSR; WIDTH AND HALF SIGNAL STA ÈALFÐOT×IDTH,X; WIDTH M2 TYA; ÒESTORE CURRENT VALUE. ; ÃALCULATE DISTANCE M3 TAY; ÂUFFER CURRENT VALUE. SEC SBC ÐOTÏLD,X PHA TYA STA ÐOTÏLD,X PLA BEQ ZERO; ÉF NOT MOVED, EXIT. BCC MINUS; ÎEGATIVE DIFFERENCE ; ÐOSITIVE DIFFERENCE: ; ÃHECK WHETHER MOVEMENT CAUSED A VALUE ; WRAP-AROUND. CMP ÈALFÐOT×IDTH,X BCC ÄECREASE BEQ ÄECREASE ; ÉT DID, SO CALCULATE "REAL" DISTANCE ; AND JUMP TO EXIT ;SEC; Ã IS ALWAYS SET HERE SBC ÐOT×IDTH,X; ÆIX DISTANCE ; ×E NOW KNOW THAT THE (FIXED) DISTANCE ; IS REALLY NEGATIVE, SO WE FINALLY ; WIPE OUT THAT ANNOYING BIT 0 NOISE BY ; INCREMENTING THE VALUE. ÉNCREASE ;CLC; Ã IS ALWAYS CLEAR HERE ADC #$01 BEQ ZERO; ÉF INCREASING ; DELIVERS ZERO, JUMP TO ZERO HANDLER. LDY #$FF; ÓET UP HIGH BYTE FOR ; NEGATIVE VALUES. RTS ; ÎEGATIVE DIFFERENCE: ; ÃHECK WHETHER MOVEMENT CAUSED A VALUE ; WRAP-AROUND. MINUS EOR #$FF; ÃOMPLEMENT ; ÉF WE WOULD DO A REAL NEGATION (BY ; ADDING "1"), THEN WE WOULD NEED TO ; BRANCH USING ÂÃÃ *AND* ÂÅÑ. ÓO THE ; ABOVE WAY MIGHT BE HARDER TO ; UNDERSTAND, BUT IT IS BOTH SHORTER ; *AND* FASTER - WHICH É LIKE. :) CMP ÈALFÐOT×IDTH,X EOR #$FF; ÒESTORE VALUE BCC ÉNCREASE ; ÍOVEMENT CAUSED A VALUE WRAP-AROUND, ; SO CALCULATE "REAL" DISTANCE AND ; EXIT. CLC ADC ÐOT×IDTH,X; ÆIX DISTANCE ; ×E NOW KNOW THAT THE (FIXED) DISTANCE ; IS REALLY POSITIVE, SO WE FINALLY ; WIPE OUT THAT ANNOYING BIT 0 NOISE BY ; DECREMENTING THE VALUE. ÄECREASE SEC SBC #$01 ; ÎO DIFFERENCE OR POSITIVE DIFFERENCE; ; BOTH NEED ZERO AS THE HIGH BYTE. ZERO LDY #0 RTS ; ÉF THERE IS NO MOUSE, RESET "LOWEST" ; ("HIGHEST" WILL HAVE BEEN RESET ; ALREADY) AND RETURN ZERO. ÒESETÍÍ TAY; ÓET Ù TO ZERO. PLA; ÔIDY STACK LDA #$FF; ÒESET "LOWEST" STA ÐOTÍIN,X TYA; ÒETURN WITH Á/Ù = 0 RTS ; --- ÉNCLUDE SPRITES ; ÂECAUSE THE Ã64 VERSION COPIES THE ; SPRITE DATA INTO THE TAPE BUFFER ON ; INITIALISATION, THE DATA IS INCLUDED ; RIGHT HERE. ; ÉN THE Ã128 VERSION, WE SKIP MEMORY ; UNTIL WE REACH $0E00 - THIS IS WHERE ; THE SPRITES ARE STORED BY DEFAULT. ; !ALIGN $FFFF,$E00,$0;Ã128 ONLY ÓPRITES !BINARY "POINTERSPRITES",, 2