;Salamax - Xbox 360 <-> PC Controller Bridge ;Brandon Wilson ;There's no license attached to this. Do whatever the f*ck you want with it. ;But you should know, if you don't document where you got it from in one of your own projects, you'll probably go to hell. include "settings.inc" ;Specific settings for this application NOLIST include "ti83plus.inc" LIST include "equates.inc" ;Equates and macros to be used include "header.asm" GLOBALS ON SEGMENT MAIN EXTERN IGetKey,PutSApp,VPutSAppCenter,StopLog,myLoadCIndPaged,myLoadDEIndPaged,SendInterruptData,BHL_plus_DE,IPutC,IPutS EXTERN SoftKey,GetHexA_StartKeyCodeA,USBactivityHook,GetHexA,DispHexHL,DispLog,DispHexA EXTERN RecycleUSB ;UI-specific equates Var lwrCaseFlag,1 Var menuAddr,2 Var numChoices,1 Var prevHookBlock,5 Var curChoice,1 Var topChoice,1 AboutScreen: ;Display the About screen ld a,(iy+plotFlags) push af set plotLoc,(iy+plotFlags) res bufferOnly,(iy+plotFlags) B_CALL ForceFullScreen B_CALL ClrLCDFull ld hl,1 ld (curRow),hl ld hl,sAboutText call PutSApp ld hl,SplashImage ld de,appBackUpScreen ld bc,SplashImageEnd-SplashImage ldir ld hl,appBackUpScreen ld de,42*256+33 B_CALL DisplayImage ld a,57 ld (penRow),a ld hl,Intro_Web call VPutSAppCenter ld a,25 ld (penRow),a ld hl,Intro_Version call VPutSAppCenter ld a,32 ld (penRow),a ld hl,Intro_Build call VPutSAppCenter pop af ld (iy+plotFlags),a xor a ld (kbdKey),a ld (kbdScanCode),a B_CALL GetKey Init: B_CALL CanAlphIns ld (iy+myFlags),0 ld hl,mainMenu ld (menuAddr),hl DrawMenu: res onInterrupt,(iy+onFlags) B_CALL ClrLCDFull B_CALL HomeUp ld hl,(menuAddr) call PutSApp ld de,0001h ld b,(hl) ld a,b ld (numChoices),a inc hl $$: push bc ld (curRow),de push de call PutSApp pop de inc e inc hl inc hl pop bc djnz $B keyLoop: B_CALL GetKey cp kQuit jr z,exitApp cp kClear jr z,exitApp cp k1 jr c,keyLoop sub k1 ld b,a ld a,(numChoices) dec a cp b jp m,keyLoop inc b push bc ld hl,(menuAddr) xor a ld bc,24 cpir inc hl pop de dec hl dec hl $$: inc hl inc hl xor a ld bc,24 cpir dec d jr nz,$B ld e,(hl) inc hl ld d,(hl) ex de,hl jp (hl) InstallHook: ld a,02h out (54h),a ld hl,USBactivityHook in a,(6) B_CALL EnableUSBActivityHook ret InitMemory: res 5,(iy+41h) res 0,(iy+41h) res errorReceived,(iy+myFlags) res keysReceived,(iy+myFlags) res packetReady,(iy+myFlags) in a,(6) ld (basePage),a xor a ld (step),a ld hl,0 ld (bufferCount),hl ld (sendBufferCount),hl ld hl,DeviceDescriptor ld (deviceDescAddress),hl ld hl,ConfigDescriptor ld (configDescAddress),hl ld hl,peripheralStatus ld de,peripheralStatus+1 ld (hl),0 ld bc,64 ldir call StartLog SetMaxPacketSize: ld hl,(deviceDescAddress) ld de,7 add hl,de ld a,(hl) ld (maxPacketSize),a ret StartLog: IF LOGGING_ENABLED = 1 di ld a,LOG_PAGE out (7),a ld hl,8000h ld (hl),0 ld de,8001h ld bc,4000h-1 ldir ld a,81h out (7),a ld hl,8000h ld b,LOG_PAGE call SetupLog ENDIF ret interrupt_start: di ex af,af' exx in a,(6) push af ld a,(basePage) out (6),a call DoInterrupt pop af out (6),a ex af,af' exx jp 0038h interrupt_end: DoInterrupt: ; ld hl,(curRow) ; push hl ; ld hl,0 ; ld (curRow),hl ; ld hl,(bufferCount) ; call DispHexHL ; ld hl,1 ; ld (curRow),hl ; ld hl,(sendBufferCount) ; call DispHexHL ; pop hl ; ld (curRow),hl in a,(0) and 3 jr z,checkForBytesToSend cp 3 jr z,checkForBytesToSend in a,(0) and 3 jr z,checkForBytesToSend cp 3 jr z,checkForBytesToSend ; in a,(9) ; push af ; bit 6,a ; jr z,$F ; set errorReceived,(iy+myFlags) ; jr checkForBytesToSend ;$$: and 11h ; jr z,checkForBytesToSend set packetReady,(iy+myFlags) res textInverse,(iy+textFlags) ;I know I have a major bug in this somewhere because this is getting set somehow... ; ;Store A to buffer ; ld bc,(bufferCount) ; ld hl,byteBuffer ; add hl,bc ; ld (hl),a ; inc bc ; ld (bufferCount),bc ; ;Now see if we have a complete packet or not ; push bc ; pop hl ; ld de,3 ; or a ; sbc hl,de ; jr c,checkForBytesToSend ;nope, less than 3 bytes ; dec bc ; dec bc ; dec bc ; ld hl,(byteBuffer+1) ; or a ; sbc hl,bc ; jr nz,checkForBytesToSend ;nope, haven't received all the data yet checkForBytesToSend: ; pop af ; bit 6,a ; jr nz,nothingToSend ; bit 5,a ; jr z,nothingToSend ;We're able to write data, do we have any to write? ld bc,(sendBufferCount) ld a,b or c jr z,nothingToSend ld hl,sendByteBuffer ;Send BC bytes at HL $$: ld a,(hl) push bc push hl call SendAByte pop hl pop bc jr c,$F inc hl dec bc ld a,b or c jr nz,$B $$: ;Shift the buffer down ld de,sendByteBuffer ld bc,100-1 ldir ld (sendBufferCount),bc ; ;Decrement the count ; dec bc ; ld (sendBufferCount),bc ; ld a,(sendByteBuffer) ; ;Shift the buffer down one ; ld hl,sendByteBuffer+1 ; ld de,sendByteBuffer ; ld bc,100-1 ; ldir ; ;Write the byte ; call DispHexA ; out (0Dh),a nothingToSend: ret SendAByte: jr SendAByte_Low push bc ld c,a $$: in a,(9) bit 6,a scf ret nz bit 5,a jr z,$B ld a,c out (0Dh),a pop bc or a ret SendAByte_Low: ld c,a ld b,8 sabBitLoop: ld de,0FFFFh rr c jr nc,$F ld a,2 jr sab1 $$: ld a,1 sab1: out (0),a $$: in a,(0) and 3 jr z,$F in a,(0) and 3 jr z,$F dec de ld a,d or e jr nz,$B scf ret $$: ld a,0 out (0),a ld de,0FFFFh $$: dec de ld a,d or e scf ret z in a,(0) and 3 cp 3 jr nz,$B djnz sabBitLoop or a ret ReceiveAByte: jr ReceiveAByte_Low push de push bc call $F pop bc pop de ret $$: ld de,0FFFFh $$: bit errorReceived,(iy+myFlags) res errorReceived,(iy+myFlags) scf ret nz in a,(9) ld b,a bit 6,a scf ret nz dec de ld a,d or e scf ret z ld a,b and 11h jr z,$B in a,(0Ah) or a ret ReceiveAByte_Low: call $F ld a,c ret $$: ld b,8 rablBitLoop: ld de,0FFFFh jr rablStart $$: in a,(0) and 3 scf ret z cp 3 jr nz,$F in a,(0) and 3 scf ret z cp 3 jr nz,$F rablStart: dec de ld a,d or e jr nz,$B scf ret $$: cp 2 jr z,rabl1 ld a,1 out (0),a rr c ld de,0FFFFh $$: in a,(0) and 3 cp 2 jr z,rabl3 dec de ld a,d or e jr nz,$B scf ret rabl3: ld a,0 out (0),a ld d,4 $$: dec d jr z,$F in a,(0) and 3 cp 3 jr nz,$B $$: djnz rablBitLoop xor a ret rabl1: ld a,2 out (0),a rr c ld de,0FFFFh rabl2: in a,(0) and 3 cp 1 jr z,rabl3 dec de ld a,d or e jr nz,rabl2 scf ret DoAction: di ld hl,interrupt_start ld de,9A9Ah ld bc,interrupt_end-interrupt_start ldir ld hl,9900h ld de,9901h ld bc,256 ld (hl),9Ah ldir ld a,99h ld i,a im 2 ei xor a; ld a,1 ld a,80h out (08h),a ;Back up previous hook, if any ld hl,9BD4h ld de,prevHookBlock ld bc,4 ldir ld hl,flags+3Ah ldi ld hl,tempMonitorVectors B_CALL AppInit set appAutoScroll,(iy+appFlags) call InstallHook call InitMemory B_CALL ClrLCDFull B_CALL HomeUp ld hl,sInstructions call PutSApp ld hl,2 ld (curRow),hl call RequestControllerStaticData mainKeyLoop: di call HandlePacketReady bit resetConnection,(iy+myFlags) res resetConnection,(iy+myFlags) jr z,$F ei call RecycleUSB jr mainKeyLoop $$: bit keysReceived,(iy+myFlags) res keysReceived,(iy+myFlags) jr z,$F call UpdateControllerStatus $$: ei nop halt B_CALL GetCSC call CheckForKeys in a,(4) bit 3,a jr nz,mainKeyLoop ActionDone: call CleanupAction jr Init HandlePacketReady: bit packetReady,(iy+myFlags) res packetReady,(iy+myFlags) ret z ; ld a,'S' ; call IPutC ld hl,byteBuffer call ReceiveAByte jr c,receiveError ld (hl),a ; call DispHexA inc hl call ReceiveAByte jr c,receiveError ld (hl),a inc hl call ReceiveAByte jr c,receiveError ld (hl),a inc hl push hl ld hl,(byteBuffer+1) ; call DispHexHL ld bc,(byteBuffer+1) ld a,b or c jr z,$F ld hl,96 or a sbc hl,bc jr nc,$F ld bc,96 $$: ld (byteBuffer+1),bc pop hl $$: ld a,b or c jr z,$F push hl push bc call ReceiveAByte pop bc pop hl jr c,receiveError ld (hl),a ; call DispHexA inc hl dec bc jr $B $$: ld a,'E' ; call IPutC ; ld a,80h ; out (8),a ; xor a ; out (8),a ld hl,0 ld (bufferCount),hl ;Now handle it ld hl,byteBuffer+3 ld de,saveSScreen ld bc,(byteBuffer+1) ld a,b or c jr z,$F ldir $$: set packetReceived,(iy+myFlags) ld a,(byteBuffer) push af cp 81h jr nz,$F set resetConnection,(iy+myFlags) $$: pop af or a ret nz set keysReceived,(iy+myFlags) ld hl,byteBuffer+3 ld de,peripheralStatus ld bc,(byteBuffer+1) ld a,b or c ret z ldir ret receiveError: ld a,'X' ; call IPutC ld hl,0 ld (bufferCount),hl ret CheckForKeys: ;A: key scan code cp sk2nd jr nz,$F set keysReceived,(iy+myFlags) ld a,01h ld (peripheralStatus+2),a ret $$: xor a ld (peripheralStatus+2),a ret CheckForStatusUpdate: call CheckForKeys ;Compare new with old ld hl,peripheralStatus+2 ld de,oldPeripheralStatus+2 ld b,30 $$: ld a,(de) cp (hl) jr nz,UpdateControllerStatus inc hl inc de djnz $B ret ;nothing's changed UpdateControllerStatus: ; ld a,5 ; call IPutC ;Copy new into old ld hl,peripheralStatus ld de,oldPeripheralStatus ld bc,32 ldir ;Send status xor a ld (peripheralStatus),a ld a,14h ld (peripheralStatus+1),a ld a,(peripheralStatus+1) ld b,a ld hl,peripheralStatus ld c,01h call SendInterruptData ; ld a,6 ; call IPutC ret RequestControllerStaticData: di ld hl,sendByteBuffer ld bc,(sendBufferCount) add hl,bc ld (hl),81h inc hl ld (hl),0 inc hl ld (hl),0 ld hl,3 ld (sendBufferCount),hl ret SendSmallPacket: di ld hl,sendByteBuffer ld (hl),1 inc hl ld (hl),1 inc hl ld (hl),0 inc hl ld (hl),'A' ld hl,4 ld (sendBufferCount),hl ret tempMonitorVectors: DW DummyRet DW DummyRet DW tempPutAway DW DummyRet DW DummyRet DW DummyRet DB appTextSaveF DummyRet: ret tempPutAway: call CleanupAction bit monAbandon,(iy+monFlags) jr nz,$F ld a,iAll out (intrptEnPort),a B_CALL LCD_DRIVERON set onRunning,(iy+onFlags) ei jr exitApp $$: B_JUMP PutAway CleanupAction: im 1 ld a,80h out (08h),a B_CALL ReloadAppEntryVecs call StopLog ;Restore previous hook, if any ld hl,prevHookBlock ld de,9BD4h ld bc,4 ldir ld de,flags+3Ah ldi call RecycleUSB ret exitApp: ld a,(lwrCaseFlag) ld (iy+appLwrCaseFlag),a B_CALL ClrLCDFull res indicOnly,(iy+indicFlags) B_JUMP JForceCmdNoChar mainMenu: DB AppName,VER_STRING,0 DB 4 DB "1) Start Bridge",0 DW DoAction DB "2) View Log",0 DW DispLog DB "3) About",0 DW AboutScreen DB "4) Quit",0 DW exitApp sAboutText: DB " Salamax " DB " Brandon Wilson ",0 SplashImage: DB 13, 30 DB 00000000b,00000000b,01100000b,00000000b DB 00000000b,00000111b,11110000b,00000000b DB 00000000b,00001111b,11110000b,00000000b DB 00000000b,00011100b,01100000b,00000000b DB 00011000b,00111000b,00000000b,00000000b DB 00111100b,01110000b,00000000b,01100000b DB 01111111b,11111111b,11111111b,11110000b DB 01111111b,11111111b,11111111b,11110000b DB 00111100b,00000111b,00000000b,01100000b DB 00011000b,00000011b,10001110b,00000000b DB 00000000b,00000001b,11111111b,00000000b DB 00000000b,00000000b,11111111b,00000000b DB 00000000b,00000000b,00001110b,00000000b SplashImageEnd: Intro_Web: DB "brandonw.net",0 Intro_Version: DB "Version ",VER_STRING,0 Intro_Build: DB "Build ",BUILD_STRING,0 sInstructions: DB "Connect your " DB "calculator to " DB "your console " DB "using a USB " DB "cable now. Press" DB LlBrack,"ON] at any time" DB "to quit.",0 DeviceDescriptor: DB 012h,001h,000h,001h,0FFh,0FFh,0FFh,040h,0ADh,01Bh,000h,0F9h,000h,001h,000h,000h,000h,001h ConfigDescriptor: DB 009h,002h DW (ConfigDescriptorEnd-ConfigDescriptorStart)+4 ConfigDescriptorStart: DB 004h,001h,000h,0A0h,0FAh,009h,004h,000h,000h,002h,0FFh,05Dh,001h,000h DB 011h,021h,010h,001h,001h,025h,081h,014h,003h,003h,003h,004h,013h,002h,008h,003h,003h,007h DB 005h,081h,003h,020h,000h,004h,007h,005h,002h,003h,020h,000h,008h,009h,004h,001h,000h,004h DB 0FFh,05Dh,003h,000h,01Bh,021h,000h,001h,001h,001h,083h,040h,001h,004h,020h,016h,085h,000h DB 000h,000h,000h,000h,000h,016h,005h,000h,000h,000h,000h,000h,000h,007h,005h,083h,003h,020h DB 000h,002h,007h,005h,004h,003h,020h,000h,004h,007h,005h,085h,003h,020h,000h,040h,007h,005h DB 005h,003h,020h,000h,010h DB 009h,004h,002h,000h,001h,0FFh,05Dh,002h,000h DB 009h,021h,000h,001h,001h,022h,086h,007h,000h DB 007h,005h,086h,003h,020h,000h,010h DB 009h,004h,003h,000h,000h,0FFh,0FDh,013h,004h DB 006h,041h,000h,001h,001h,003h ConfigDescriptorEnd: StringDescriptor4: DB 0B2h,003h,058h,000h,062h,000h,06Fh,000h,078h,000h,020h,000h,053h,000h,065h,000h,063h,000h DB 075h,000h,072h,000h,069h,000h,074h,000h,079h,000h,020h,000h,04Dh,000h,065h,000h,074h,000h DB 068h,000h,06Fh,000h,064h,000h,020h,000h,033h,000h,02Ch,000h,020h,000h,056h,000h,065h,000h DB 072h,000h,073h,000h,069h,000h,06Fh,000h,06Eh,000h,020h,000h,031h,000h,02Eh,000h,030h,000h DB 030h,000h,02Ch,000h,020h,000h,0A9h,000h,020h,000h,032h,000h,030h,000h,030h,000h,035h,000h DB 020h,000h,04Dh,000h,069h,000h,063h,000h,072h,000h,06Fh,000h,073h,000h,06Fh,000h,066h,000h DB 074h,000h,020h,000h,043h,000h,06Fh,000h,072h,000h,070h,000h,06Fh,000h,072h,000h,061h,000h DB 074h,000h,069h,000h,06Fh,000h,06Eh,000h,02Eh,000h,020h,000h,041h,000h,06Ch,000h,06Ch,000h DB 020h,000h,072h,000h,069h,000h,067h,000h,068h,000h,074h,000h,073h,000h,020h,000h,072h,000h DB 065h,000h,073h,000h,065h,000h,072h,000h,076h,000h,065h,000h,064h,000h,02Eh,000h StringDescriptor4End: