!! USB Steering Wheel Driver
tested with the patched Pole Position Game (download, see Sourceforge File Area. [http://sourceforge.net/projects/microusb/files/] ) and the Thrustmaster Nascar Pro Digital 2 Steering Wheel.
Source is in Bibo-Assembler Format.
{{{
01000 .LI OFF
01010 **************************
01020 ** 6502 USB DEVELOPMENT **
01030 ** (C) 2004 BY ABBUC **
01040 ** REGINALGRUPPE FFM **
01050 ** STEERING WHEEL DRIVER**
01060 ** FOR USB SL811HS **
01070 ** VERSION 1.1 20041030 **
01080 ** POLEPOSITION PATCH **
01090 **************************
01100 ;
01110 .OR $2500
01120 .OF "D:USBWHEEL.COM"
01130 ;
01140 ; SL811 MEMORY ADDRESSES
01150 ; CHANGE ACCORDING TO YOUR
01160 ; CONFIGURATION
01170 ;
01180 USBSEL = $D500
01190 USBDTA = $D501
01200 ;
01210 ; USB DEVICE WAIT
01220 ; CHANGE IF NEEDED
01230 ;
01240 USBWAIT = $20
01250 ;
01260 ; USB REGISTER SL811
01270 ;
01280 CTL = $00 ; USBA HOST CTL
01290 BUFADR = $01 ; BUFFER ADDRESS
01300 BUFLEN = $02 ; BUFFER LEN
01310 PIDEP = $03 ; HOST PID
01320 PKSTAT = $03 ; PAKET STATUS
01330 FNADDR = $04 ; USB ADDR (WO)
01340 MCNTRL = $05 ; MAIN CONTROL
01350 CDTASET = $0E
01360 SOFCNT = $0F ; CNTRL 2 REG
01370 SOFLOW = $0E ; SOF LOW
01380 INTSTAT = $0D ; IRQ STATUS
01390 ;
01400 ; USB CONSTANTS
01410 ;
01420 ; INTENA AND INTSTAT MASKS
01430 EP0DONE = $01
01440 EP1DONE = $02
01450 EP2DONE = $04
01460 EP3DONE = $08
01470 DMADONE = $10
01480 SOFRECV = $20
01490 USBRSET = $40
01500 DMASTAT = $80
01510 ;
01520 ; ENDPOINT CONTROL REG
01530 ;
01540 EPC0 = $00 ; ENDPOINT 0
01550 EPC1 = $10 ; ENDPOINT 1
01560 EPC2 = $20 ; ENDPOINT 2
01570 EPC3 = $30 ; ENDPOINT 3
01580 ;
01590 ; ENDPOINT REGISTER OFFSET
01600 ;
01610 EPC = $00 ; CONTROL
01620 EPBA = $01 ; BASE ADDRESS
01630 EPBL = $02 ; BASE LENGTH
01640 EPPS = $03 ; PACKET STATUS
01650 EPTC = $04 ; TRANSFERCOUNT
01660 ;
01670 ; PID VALUES
01680 ;
01690 SOFPID = $05 ; SOF PID
01700 INPID = $90 ; PACKET ID
01710 SETPID = $D0 ; SET ADDRESS REQ
01720 ;
01730 ; SET ADDRESS PACKET
01740 ;
01750 SETADDR .HX 0005010000000000
01760 ;
01770 ; SET CONFIG PACKET
01780 ;
01790 SETCONF .HX 0009010000000000
01800 ;
01810 ; ATARI MEMORY LOCATIONS
01820 STICK0 = $600 ; $278
01830 STRIG0 = $601 ; $284
01840 VCOUNT = $D40B
01850 ;
01860 ------------------------------
01870 ; RESET THE SL811HS USB
01880 ; CONTROLLER
01890 ;
01900 USBRESET
01910 LDA #$AE ; SET SOF
01920 LDX #SOFCNT ; HIGH COUNT
01930 JSR REGSTORE
01940 ;
01950 LDA #$08 ; RESET USB
01960 LDX #MCNTRL ; FULLSPEED
01970 JSR REGSTORE
01980 ;
01990 LDA #USBWAIT
02000 JSR PAUSE
02010 ;
02020 LDA #00
02030 LDX #MCNTRL
02040 JSR REGSTORE
02050 ;
02060 RTS
02070 ------------------------------
02080 ; OUT: A=0 NO USB RESET
02090 ; A!=0 USBRESET
02100 ;
02110 ; CHECK IF AN USB RESET
02120 ; OCCURED
02130 ;
02140 QUERYUSBRESET
02150 LDX #INTSTAT
02160 JSR REGFETCH
02170 AND #USBRSET
02180 RTS
02190 ------------------------------
02200 ; CLEAR USB IRQ MASKS
02210 ;
02220 CLEARIRQ
02230 LDA #$FF
02240 LDX #INTSTAT
02250 JMP REGSTORE
02260 ------------------------------
02270 ; DETECT USB DEVICE SPEED
02280 ;
02290 ; OUT: A=0 LOW SPEED DEVICE
02300 ; A!=0 HIGH SPEED DEVICE
02310 ; OR ERROR
02320 ;
02330 SPEED JSR USBRESET
02340 JSR CLEARIRQ
02350 LDA #USBWAIT
02360 JSR PAUSE
02370 JSR QUERYUSBRESET
02380 BEQ .1 ; NO RESET
02390 JSR CLEARIRQ
02400 LDA #$FF
02410 RTS
02420 ;
02430 .1 LDX #INTSTAT
02440 JSR REGFETCH
02450 AND #DMASTAT
02460 BNE .2
02470 ;
02480 ; LOW SPEED
02490 ;
02500 LDA #$AE
02510 LDX #SOFCNT
02520 JSR REGSTORE
02530 ;
02540 LDA #$E0
02550 LDX #CDTASET
02560 JSR REGSTORE
02570 ;
02580 LDA #$05
02590 LDX #MCNTRL
02600 JSR REGSTORE
02610 ;
02620 JSR SETUPUSB
02630 LDA #$00
02640 ;
02650 ; FULL SPEED OR ERROR
02660 ;
02670 .2
02680 RTS
02690 ------------------------------
02700 ; SET UP USB CONTROLLER FOR
02710 ; DEVICE COMMUNICATION
02720 ;
02730 SETUPUSB
02740 LDA #$50
02750 LDX #EPC0+EPPS
02760 JSR REGSTORE
02770 ;
02780 LDA #$00
02790 LDX #EPC0+EPTC
02800 JSR REGSTORE
02810 ;
02820 LDA #$01
02830 LDX #EPC0
02840 JSR REGSTORE
02850 ;
02860 LDA #USBWAIT
02870 JSR PAUSE
02880 ;
02890 JSR CLEARIRQ
02900 RTS
02910 ------------------------------
02920 ; ASSIGN USB ADDRESS 1 TO
02930 ; DEVICE, SELECT CONFIGURATION
02940 ; PROFILE 1
02950 ;
02960 INITWHEEL
02970 LDA #08
02980 LDX #MCNTRL
02990 JSR REGSTORE
03000 ;
03010 LDA #USBWAIT
03020 JSR PAUSE
03030 ;
03040 LDA #$21
03050 LDX #MCNTRL
03060 JSR REGSTORE
03070 ;
03080 LDA #$10 ; $10 ADDR
03090 LDX #BUFADR ; DATABUF
03100 JSR REGSTORE
03110 ;
03120 LDA #$8 ; 8 BYTE
03130 LDX #BUFLEN ; DATABUF
03140 JSR REGSTORE
03150 ;
03160 LDA #$E0 ; 1MS EOP
03170 LDX #SOFLOW
03180 JSR REGSTORE
03190 ;
03200 LDA #$EE
03210 LDX #SOFCNT
03220 JSR REGSTORE
03230 ;
03240 ; SET BUFFER FOR SETUP-ADDRESS
03250 ; REQUEST = 1
03260 ;
03270 LDY #8
03280 .1 TYA
03290 CLC
03300 ADC #$F ; BUF ADDR
03310 TAX
03320 LDA SETADDR-1,Y
03330 JSR REGSTORE
03340 DEY
03350 BNE .1
03360 ;
03370 LDA #00 ; WE USE
03380 LDX #FNADDR ; ADDR 0
03390 JSR REGSTORE
03400 ;
03410 LDA #SETPID
03420 LDX #PIDEP
03430 JSR REGSTORE
03440 ;
03450 .2 LDA #07
03460 JSR PROCESS
03470 AND #04
03480 BNE .2
03490 ;
03500 LDA #USBWAIT
03510 JSR PAUSE
03520 ;
03530 LDA #INPID
03540 LDX #PIDEP
03550 JSR REGSTORE
03560 ;
03570 LDA #03
03580 JSR PROCESS
03590 ;
03600 ; SELECT CONFIGURATION 1
03610 ;
03620 LDY #8
03630 .3 TYA
03640 CLC
03650 ADC #$F
03660 TAX
03670 LDA SETCONF-1,Y
03680 JSR REGSTORE
03690 DEY
03700 BNE .3
03710 ;
03720 LDA #01
03730 LDX #FNADDR ; NEW ADDR
03740 JSR REGSTORE
03750 ;
03760 LDA #SETPID
03770 LDX #PIDEP
03780 JSR REGSTORE
03790 ;
03800 .4 LDA #07
03810 JSR PROCESS
03820 AND #04
03830 ;
03840 BNE .4
03850 ;
03860 LDA #INPID
03870 LDX #PIDEP
03880 JSR REGSTORE
03890 ;
03900 LDA #03
03910 JSR PROCESS
03920 ;
03930 LDA #INPID
03940 ORA #01
03950 LDX #PIDEP
03960 JSR REGSTORE
03970 ;
03980 RTS
03990 ------------------------------
04000 ; TEXTOUTPUT WITH THE HELP
04010 ; OF THE STACK. TEXT IS
04020 ; STORED NEXT TO THE JSR TO
04030 ; THIS ROUTINE. TEXT-END MARKER
04040 ; IS '@'
04050 ;
04060 PRINT PLA ; Return Adress
04070 STA $D0 ; from Stack
04080 PLA ; and store
04090 STA $D1 ; as pointer
04100 ;
04110 INCP INC $D0 ; increase
04120 BNE .1 ; pointer
04130 INC $D1
04140 .1 LDX #0 ; read char
04150 LDA ($D0,X); from RAM
04160 CMP #'@ ; End?
04170 BEQ ENDPR ; yes=>
04180 JSR PUTCHAR ; Print Char
04190 JMP INCP ; back to loop
04200 *
04210 ENDPR LDA $D1 ; store pointer
04220 PHA ; as new Return
04230 LDA $D0 ; address on
04240 PHA ; Stack
04250 RTS ; continue Program
04260 ; after text
04270 ------------------------------
04280 ; Print one char
04290 ; in: A= Char to print
04300 ;
04310 PUTCHAR TAX Print
04320 LDA $E407 char
04330 PHA with OS
04340 LDA $E406 Routine on
04350 PHA Stack
04360 TXA
04370 RTS JUMP
04380 ------------------------------
04390 ; wait for HID Device to be
04400 ; plugged into the USB Cart
04410 ;
04420 WAITWHEEL
04430 JSR PRINT
04440 .HX 9B
04450 .AS "ATARI USB STEERING WHEEL DRIVER"
04460 .HX 9B
04470 .AS "FOR POLEPOSITION"
04480 .HX 9B
04490 .AS "(c) 2004 ABBUC e.V."
04500 .HX 9B
04510 .AS "H. Reminder, T. Grasel, C. Strotmann"
04520 .HX 9B9B
04530 .AS "WAIT FOR DEVICE..."
04540 .HX 9B40
04550 .1 JSR SPEED
04560 CMP #0
04570 BNE .1
04580 JSR PRINT
04590 .AS "LOW SPEED DEVICE DETECTED!"
04600 .HX 9B40
04610 ;
04620 JSR INITWHEEL
04630 JSR PRINT
04640 .AS "WHEEL INITILIZED."
04650 .HX 9B40
04660 CLC
04670 RTS
04680 ------------------------------
04690 ; RESIDENT PART OF THE DRIVER
04700 ; THIS WILL STAY IN MEMORY
04710 ; AND SHOULD NOT BE OVERWRITTEN
04720 ;
04730 RESPART .OR $7F00
04740 ------------------------------
04750 ; GET JOYSTICK VALUES
04760 ;
04770 GETSTICK
04780 TXA
04790 PHA ; SAVE XREG
04800 JSR QUERYWHEEL
04810 LDY STICK0
04820 PLA
04830 TAX ; REST XREG
04840 RTS
04850 ------------------------------
04860 ; GET JOYSTICK TRIGGER
04870 ;
04880 GETTRIG
04890 TXA
04900 PHA ; SAVE XREG
04910 TYA
04920 PHA ; SAVE YREG
04930 JSR QUERYWHEEL
04940 PLA
04950 TAY ; REST YREG
04960 PLA
04970 TAX ; REST XREG
04980 LDA STRIG0
04990 RTS
05000 ------------------------------
05010 ; FETCH AN USB REGISTER VALUE
05020 ; IN: X=USB REGISTER
05030 ; OUT: A=USB DATA
05040 ;
05050 REGFETCH STX USBSEL
05060 LDA USBDTA
05070 RTS
05080 ------------------------------
05090 ; STORE AN USB REGISTER VALUE
05100 ; IN: A=USB DATA
05110 ; X=USB REGISTER
05120 ;
05130 REGSTORE STX USBSEL
05140 STA USBDTA
05150 RTS
05160 ------------------------------
05170 ; PAUSE FOR 1/50 SECONDS
05180 ; IN: A=NUMBER OF 1/50 SEC
05190 ;
05200 PAUSE TAX
05210 .1 LDA VCOUNT
05220 BNE .1
05230 DEX
05240 BNE .1
05250 RTS
05260 ------------------------------
05270 ; QUERY WHEEL DEVICE
05280 ;
05290 QUERYWHEEL
05300 ;
05310 LDA #03 ; POLL USB
05320 JSR PROCESS
05330 AND #01
05340 BEQ .2 ; NO DATA
05350 ;
05360 LDX #$10 LOAD
05370 JSR REGFETCH TRIGGER
05380 STA TRIGGER
05390 LDX #$12 LOAD
05400 JSR REGFETCH WHEEL
05410 STA WHEEL
05420 LDX #$13 LOAD
05430 JSR REGFETCH PEDAL
05440 STA PEDAL
05450 JSR USB2ATA
05460 .2 RTS
05470 ------------------------------
05480 TRIGGER .HX 00 ; TRIGGER
05490 WHEEL .HX 00 ; WHEEL
05500 PEDAL .HX 00 ; PEDAL
05510 ------------------------------
05520 ; SEND USB COMMAND
05530 ; IN: A=USB COMMAND
05540 ; OUT: A=RETURNCODE
05550 PROCESS PHA
05560 LDA #01
05570 LDX #INTSTAT
05580 JSR REGSTORE
05590 ;
05600 PLA
05610 LDX #CTL
05620 JSR REGSTORE
05630 ;
05640 .1 LDX #INTSTAT
05650 JSR REGFETCH
05660 AND #$01
05670 BEQ .1
05680 ;
05690 LDX #PKSTAT
05700 JSR REGFETCH
05710 RTS
05720 ------------------------------
05730 ; CONVERT USB WHEEL VALUES
05740 ; TO ATARI STICK/STRIG VALUES
05750 ; FOR POLEPOSITION
05760 ;
05770 USB2ATA
05780 LDA #15 ; STORE
05790 STA STICK0 ; DEFAULT
05800 LDA #1 ; VALUES
05810 STA STRIG0
05820 ;
05830 SHIFT LDA TRIGGER ; TRIGGER
05840 AND #3 ; SHIFT?
05850 BEQ STEER ; NO!
05860 LDA TRIGGER
05870 AND #1
05880 BEQ .1
05890 LDA #13 ; SHIFT LOW
05900 .2 STA STICK0
05910 RTS
05920 .1 LDA #14 ; SHIFT HIGH
05930 BNE .2
05940 STEER LDA WHEEL ; LOAD WHEEL
05950 BPL .1 ; NEG?
05960 EOR #$FF ; YES->INVERT
05970 .1 AND #$F8 ; +/-8 TRESHOLD
05980 BEQ PEDL ; NO STEERING
05990 LDA WHEEL
06000 BMI .2 ; LEFT
06010 LDA #7
06020 BNE .3
06030 .2 LDA #11 ; RIGHT
06040 .3 STA STICK0
06050 ;
06060 PEDL LDA PEDAL ; PEDAL?
06070 BPL .1 ; BREAKS?
06080 LDA #0 ; YES->BREAK!
06090 STA STRIG0
06100 .1
06110 RTS
06120 ------------------------------
06130 ; INIT VECTOR
06140 .OR $2E2
06150 .DA WAITWHEEL
06160 ------------------------------
}}}