ORG $C000 JOY = $0500 ; SO YOU CAN SEE, IF SOMETHING HAPPENS ; OTHERWISE ZEROPAGE SHOULD BE PREFERRED SEI LDX #<(IRQ) ; STANDARD... LDY #>(IRQ) ; PROCEDURE... STX $0314 ; FOR... STY $0315 ; SETTING... LDA #$81 ; UP... STA $D01A ; AN... LDA #$FF ; IRQ-ROUTINE. STA $D012 ; NOTHING... LDA #$1B ; SPECIAL... STA $D011 ; ABOUT... CLI ; IT.. RTS ; RETURN TO BASIC... IRQ: LDA $D019 ; GET IRQ-FLAG BPL NOIRQ ; IRQ GENERATED BY VIC? STA $D019 ; YES, THEN CLEAR FLAG JSR GETSNES ; MAIN ROUTINE NOIRQ: ; THIS ROUTINE WILL PREVENT THE PADS FROM INTERFERING WITH THE ; KEYBOARD. IT IS NECESSARY AS WE NEED TO RESET $DC03 TO ZERO FOR THE ; KEYBOARD SCAN. UNFORTUNATELY THIS CAUSES A PERMANENT HIGH SIGNAL ON ; OUR SNES-RESET-LINE, WHAT MEANS WE ALWAYS HAVE THE STATUS BIT FROM ; BUTTON B PRESENT ON $DC01. SO, THIS IS HOW YOU CAN GET AROUND THAT ; LITTLE PROBLEM. LDA #$FF ; DISABLE KEYS BY SETTING ALL KEYBOARD STA $DC00 ; SCAN LINES HIGH... CMP $DC01 ; ...SO ANY LOW SIGNAL MUST BE SENT BY A PAD BNE NOKEYB ; DID WE GET AN INTERFERENCE? JMP $EA31 ; NO, THEN WE CAN CHECK THE KEYBOARD NOKEYB: JMP $EA7E ; YES, SKIP KEYBOARD THIS TIME ; THE FOLLOWING ROUTINE GRABS ALL THE BITS FROM THE SNES-PADS. ; OF COURSE, THIS CODE ISN'T OPTIMIZED, SINCE IT IS ONLY FOR ; DEMONSTRATION PURPOSES. ANYWAY, HERE ARE THE BIT DESCRIPTIONS IN THE ; ORDER AS THEY ARE SENT BY THE PAD. ROL THEM, ROR THEM, READ THEM AT ; ONCE FOR ALL 8 PADS, OR WHATEVER. YOU HAVE QUITE A NUMBER OF OPTIONS ; :) ; ; BIT 0 : BUTTON B ; BIT 1 : BUTTON Y ; BIT 2 : SELECT ; BIT 3 : START ; BIT 4 : UP ; BIT 5 : DOWN ; BIT 6 : LEFT ; BIT 7 : RIGHT ; BIT 8 : BUTTON A ; BIT 9 : BUTTON X ; BIT 10 : TOP-LEFT L ; BIT 11 : TOP-RIGHT R ; BIT 12+: ALWAYS 1 ; ; NORMALLY A CLEARED BIT MEANS 'BUTTON PRESSED'. OF COURSE, YOU CAN ; CHANGE THIS BY USING AN EOR #$?? COMMAND. GETSNES: LDA #$00 ; PA 0-7 = INPUT STA $DC02 ; LDA #$F8 ; PB 0-2 = INPUT STA $DC03 ; PB 3-7 = OUTPUT LDA #$10 ; SEND "RESET" COMMAND STA $DC01 ; TO ALL PADS LDA #0 ; AND STA $DC01 ; CLEAR IT LDY #16 ; GET 16 BITS (WE ACTUALLY NEED ONLY 12 ; BITS, BUT THIS WAY WE HAVE CONSTANT LOOP3: ; VALUES ON THE SCREEN.) LDX #14 ; COUNTER FOR 8 PADS LDA $DC01 ; GET DATA FROM JOYPORT 1 EOR #7 ; INVERT BITS FROM PADS (NOT NECESSARY) LOOP1: LSR ; SHIFT BIT FROM PAD INTO CARRY... ROL JOY+0,X ; ...THEN INTO ITS DESTINATION ROL JOY+1,X ; ...ROTATE 16 BITS DEX ; DECREMENT COUNTER BY 2 AS WE USE DEX ; TWO BYTES FOR STORAGE CPX #8 ; FIRST THREE PADS DONE? BNE LOOP1 ; NO? THEN CONTINUE LDA $DC00 ; GET DATA FROM JOYPORT 2 EOR #$1F ; INVERT BITS FROM PADS (NOT NECESSARY) LOOP2: LSR ; SHIFT BIT FROM PAD INTO CARRY... ROL JOY+0,X ; ...THEN INTO ITS DESTINATION ROL JOY+1,X ; ...ROTATE 16 BITS DEX ; AGAIN DECREMENT COUNTER DEX BPL LOOP2 ; ALL DONE? LDA #8 ; SEND "NEXT" COMMAND STA $DC01 ; TO ALL PADS LDA #0 ; AND STA $DC01 ; CLEAR IT DEY ; DID WE GET 12 BITS? BNE LOOP3 ; IF NOT, LOOP LDA #$FF ; BACK... STA $DC02 ; TO... LDA #$00 ; NORMAL... STA $DC03 ; FOR KEYBOARD SCAN. RTS ; GO BACK... ; IF YOU USE THE ROL INSTRUCTION TO COLLECT THE BITS FROM THE PAD, ; YOU CAN USE THIS TABLE TO FIX THE DIRECTIONS, SO THAT IT IS ; COMPATIBLE WITH THE STANDARD C64 FORMAT. SIMPLY ISOLATE THE ; DIRECTION-BITS AND USE THEM AS AN INDEX. BY THE WAY USE THE ROR ; INSTRUCTION AND YOU WON'T HAVE THIS PROBLEM... FIXTAB: BYT $00,$08,$04,$0C,$02,$0A,$06,$0E BYT $01,$09,$05,$0D,$03,$0B,$07,$0F