;USB activity hook include "settings.inc" include "ti83plus.inc" include "equates.inc" SEGMENT Main GLOBALS ON EXTERN DispHexA,DispHexHL,GetControlPacket,WaitPort82,SetupOutPipe,SetupInPipe,SendInterruptData EXTERN debugStep,col1,col2,SmallWaitTimer,WaitTimerBms,SendBulkData,handleCalcData,RecycleUSB EXTERN DoDebug,ReceiveData,InitializePeriphUSB,receiveAndWriteUSBData,WaitTimer20ms,WaitTimer40ms EXTERN IPutC,SetupLog,LoadPS3JBSettings,BHL_plus_DE,myLoadCIndPaged,myLoadDEIndPaged,inc_BHL,GetCompatibilityData EXTERN HUB_READY,P1_READY,P2_READY,P3_READY,P4_READY,DONE,JB_INIT,P2_WAIT_RESET,P5_WAIT_DISCONNECT EXTERN P4_WAIT_DISCONNECT,P5_WAIT_RESET,P5_WAIT_ENUMERATE,P4_WAIT_RESET,P1_WAIT_DISCONNECT EXTERN P6_WAIT_RESET,P6_WAIT_ENUMERATE,P3_WAIT_DISCONNECT,P5_CHALLENGED,P4_WAIT_ENUMERATE EXTERN P2_WAIT_DISCONNECT,P2_WAIT_ENUMERATE,P1_WAIT_ENUMERATE,P2_WAIT_DISCONNECT,P3_WAIT_RESET EXTERN P3_WAIT_ENUMERATE,P1_WAIT_RESET,JIG_INIT EXTERN Device4ConfigDescriptor2Short,Device4ConfigDescriptor2,Device4ConfigDescriptor3,JigDeviceDescriptor,JigConfigDescriptor EXTERN SendDevice1ConfigDescriptor,ReceiveInterruptData,SendDevice3ConfigDescriptor,AsbestOSDeviceDescriptor EXTERN Device4DeviceDescriptor,Device4ConfigDescriptor1,Device5DeviceDescriptor,Device5ConfigDescriptor EXTERN Device1DeviceDescriptor,Device1ShortConfigDescriptor,Device1ConfigDescriptor,Device2DeviceDescriptor EXTERN HubDeviceDescriptor,HubConfigDescriptor,Device3DeviceDescriptor,Device3ConfigDescriptor,Device2ConfigDescriptor EXTERN Device6DeviceDescriptor,Device6ConfigDescriptor,SendDevice4ConfigDescriptor,sha1_hash EXTERN HMACInit,HMACAddByte,HMACDone ;Variables the jailbreak is dependent on (these need to be moved to OS-safe memory) PS3JailbreakMemory EQU 0FE67h deviceBitmap EQU PS3JailbreakMemory ;12 deviceChangedBitmap EQU deviceBitmap+12 ;12 deviceAddressMap EQU deviceChangedBitmap+12 ;7 jailbreakState EQU deviceAddressMap+7 ;1 lastPortResetClear EQU jailbreakState+1 ;1 lastPortConnClear EQU lastPortResetClear+1 ;1 lastPortStatus EQU lastPortConnClear+1 ;1 hubIntResponse EQU lastPortStatus+1 ;1 portCur EQU hubIntResponse+1 ;1 curAddressIndex EQU portCur+1 ;1 maxPacketSize EQU curAddressIndex+1 ;1 jigBytesReceived EQU maxPacketSize+1 ;1 descSize EQU jigBytesReceived+1 ;2 descSizeOverride EQU descSize+2 ;2 shortConfigDescAddress EQU descSizeOverride+2 ;3 deviceDescAddress EQU shortConfigDescAddress+3 ;3 configDescAddress EQU deviceDescAddress+3 ;3 InitJailbreakMemory: xor a ld (lastPortResetClear),a ld (lastPortConnClear),a ld (hubIntResponse),a ld (portCur),a ld (curAddressIndex),a ld (lastPortResetClear),a ld (jigBytesReceived),a res overrideSize,(iy+PS3JBFlags) res useShortConfigDesc,(iy+PS3JBFlags) res sentInterruptData,(iy+PS3JBFlags) res useStage2Payload,(iy+PS3JBFlags) res 5,(iy+41h) res 0,(iy+41h) ld hl,deviceBitmap ld bc,12 B_CALL MemClear ld hl,deviceChangedBitmap ld bc,12 B_CALL MemClear ld hl,deviceAddressMap ld bc,7 B_CALL MemClear call LoadPS3JBSettings bit 1,(iy+asm_Flag2) jr nz,emulateJig ld a,JB_INIT call SetJailbreakState ld hl,HubDeviceDescriptor ld (deviceDescAddress),hl ld hl,HubConfigDescriptor ld (configDescAddress),hl jr $F emulateJig: ld a,JIG_INIT call SetJailbreakState ld hl,JigDeviceDescriptor ld (deviceDescAddress),hl ld hl,JigConfigDescriptor ld (configDescAddress),hl $$: 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,83h 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,83h call SetupLog ENDIF ret SwitchPort: ld hl,portCur ld b,(hl) cp b ret z ld (hl),a ld hl,deviceAddressMap ld b,0 ld c,a add hl,bc ld a,(hl) SetDeviceAddress: out (80h),a ld (USBaddress),a push af ld hl,deviceAddressMap ld bc,(portCur) ld b,0 add hl,bc pop af ld (hl),a ret SetJailbreakState: ld (jailbreakState),a LOG StateChange,a ret ConnectPort: push af ld b,0 ld c,a ld hl,deviceBitmap add hl,bc add hl,bc ld (hl),03h inc hl ld (hl),01h ld hl,deviceChangedBitmap add hl,bc add hl,bc ld (hl),01h inc hl ld (hl),00h pop af inc a ld d,1 or a $$: rl d dec a jr nz,$B ld a,d ld (hubIntResponse),a ret DisconnectPort: push af ld b,0 ld c,a ld hl,deviceBitmap add hl,bc add hl,bc ld (hl),00h inc hl ld (hl),01h ld hl,deviceChangedBitmap add hl,bc add hl,bc ld (hl),01h inc hl ld (hl),00h pop af inc a ld d,1 or a $$: rl d dec a jr nz,$B ld a,d ld (hubIntResponse),a ret HandleJailbreakStateChanges: ld a,(jailbreakState) cp P1_READY jr nz,$F xor a call SwitchPort ld a,P2_WAIT_RESET call SetJailbreakState xor a ld (lastPortResetClear),a ld a,1 call ConnectPort jr HandleJailbreakStateChanges $$: ld a,(jailbreakState) cp HUB_READY jr nz,$F ld a,P1_WAIT_RESET call SetJailbreakState xor a call ConnectPort jr HandleJailbreakStateChanges $$: ld a,(hubIntResponse) or a jr z,$F push af xor a ld (hubIntResponse),a pop af ld b,01h ld c,01h ld hl,OP1 ld (hl),a call SendInterruptData $$: ld a,(jailbreakState) cp P2_READY jr nz,$F xor a call SwitchPort ld a,P3_WAIT_RESET call SetJailbreakState xor a ld (lastPortResetClear),a ld a,2 call ConnectPort jr HandleJailbreakStateChanges $$: ld a,(jailbreakState) cp P3_WAIT_RESET jr nz,$F ld a,(lastPortResetClear) cp 3 jr nz,$F ld a,3 call SwitchPort ld hl,Device3DeviceDescriptor ld (deviceDescAddress),hl call SetMaxPacketSize ld hl,Device3ConfigDescriptor ld (configDescAddress),hl res useShortConfigDesc,(iy+PS3JBFlags) ld a,P3_WAIT_ENUMERATE call SetJailbreakState jr HandleJailbreakStateChanges $$: ld a,(jailbreakState) cp P3_READY jr nz,$F xor a call SwitchPort ld a,1 ;this is port 2 call DisconnectPort ld a,P2_WAIT_DISCONNECT call SetJailbreakState jr HandleJailbreakStateChanges $$: ld a,(jailbreakState) cp P1_WAIT_RESET jr nz,$F ld a,(lastPortResetClear) cp 1 jr nz,$F ;Time to switch the address and start listening to device 1 ld a,1 call SwitchPort ld hl,Device1DeviceDescriptor ld (deviceDescAddress),hl call SetMaxPacketSize ld hl,Device1ShortConfigDescriptor ld (shortConfigDescAddress),hl ld hl,Device1ConfigDescriptor ld (configDescAddress),hl set useShortConfigDesc,(iy+PS3JBFlags) ld a,P1_WAIT_ENUMERATE call SetJailbreakState jr HandleJailbreakStateChanges $$: ld a,(jailbreakState) cp P2_WAIT_RESET jr nz,$F ld a,(lastPortResetClear) cp 2 jr nz,$F ;Time to switch the address and start listening to device 2 ld a,2 call SwitchPort ld hl,Device2DeviceDescriptor ld (deviceDescAddress),hl call SetMaxPacketSize ld hl,Device2ConfigDescriptor ld (configDescAddress),hl res useShortConfigDesc,(iy+PS3JBFlags) ld a,P2_WAIT_ENUMERATE call SetJailbreakState jr HandleJailbreakStateChanges $$: ld a,(jailbreakState) cp P2_WAIT_DISCONNECT jr nz,$F ld a,(lastPortConnClear) cp 2 jr nz,$F res sentInterruptData,(iy+PS3JBFlags) ld a,P4_WAIT_RESET call SetJailbreakState xor a ld (lastPortResetClear),a ld (lastPortStatus),a ld a,3 ;port 4 call ConnectPort in a,(8Eh) push af ld a,1 out (8Eh),a in a,(91h) and 0EFh or 40h out (91h),a pop af out (8Eh),a jr HandleJailbreakStateChanges $$: ld a,(jailbreakState) cp P4_WAIT_RESET jr nz,$F bit sentInterruptData,(iy+PS3JBFlags) jr nz,sentPort4Change ld a,(lastPortStatus) cp 02h jr nz,$F set sentInterruptData,(iy+PS3JBFlags) ld a,10h ld (hubIntResponse),a jr HandleJailbreakStateChanges sentPort4Change: ld a,(lastPortResetClear) cp 4 jr nz,$F ld a,4 call SwitchPort ld a,P4_WAIT_ENUMERATE call SetJailbreakState ld hl,Device4DeviceDescriptor ld (deviceDescAddress),hl call SetMaxPacketSize ld hl,Device4ConfigDescriptor1 ld (configDescAddress),hl res useShortConfigDesc,(iy+PS3JBFlags) jr HandleJailbreakStateChanges $$: ld a,(jailbreakState) cp P4_READY jr nz,$F connectJig: xor a call SwitchPort ld a,P5_WAIT_RESET call SetJailbreakState res sentInterruptData,(iy+PS3JBFlags) xor a ld (lastPortResetClear),a ld a,4 call ConnectPort in a,(8Eh) push af ld a,1 out (8Eh),a in a,(91h) and 0EFh or 40h out (91h),a pop af out (8Eh),a jr HandleJailbreakStateChanges $$: ld a,(jailbreakState) cp P5_WAIT_RESET jr nz,$F ld a,(lastPortResetClear) cp 5 jr nz,$F ;Time to switch the address and start listening to device 5 ld a,5 call SwitchPort ld hl,Device5DeviceDescriptor ld (deviceDescAddress),hl call SetMaxPacketSize ld hl,Device5ConfigDescriptor ld (configDescAddress),hl res useShortConfigDesc,(iy+PS3JBFlags) ld a,P5_WAIT_ENUMERATE call SetJailbreakState jr HandleJailbreakStateChanges $$: ld a,(jailbreakState) cp P5_WAIT_ENUMERATE jr nz,$F ld a,(jigBytesReceived) cp 64 jr c,$F ld a,P5_CHALLENGED call SetJailbreakState call WaitTimer20ms ;Get the jig response data call LoadPS3JBSettings ;Default to built-in data first ld hl,jigResponse ld de,externalDataBuffer ld bc,64 ldir xor a call GetCompatibilityData ;Send the jig response data ld hl,externalDataBuffer ld b,8 sendJigResponseLoop: push bc ld b,8 ld c,01h push hl call SendInterruptData pop hl ld de,8 add hl,de pop bc djnz sendJigResponseLoop call WaitTimer20ms ;Disconnect port 3 xor a call SwitchPort ld a,2 call DisconnectPort ;At this point, the exploit will fire. We need to disconnect the other devices and connect 6 to get the confirmation so the payload can finish executing. xor a ld (lastPortStatus),a ld a,P3_WAIT_DISCONNECT call SetJailbreakState res sentInterruptData,(iy+PS3JBFlags) jr HandleJailbreakStateChanges $$: ld a,(jailbreakState) cp JIG_INIT jr nz,$F ld a,(jigBytesReceived) cp 64 jr c,$F ;Calculate the jig response data call HMACInit ld hl,jigChallengeData+7 ld b,20 hashChallengeLoop: push bc push hl ld a,(hl) call HMACAddByte pop hl inc hl pop bc djnz hashChallengeLoop call HMACDone ;Build jig response ld hl,externalDataBuffer ld bc,64 B_CALL MemClear ld ix,externalDataBuffer ld (ix+0),0 ld (ix+1),0 ld (ix+2),0FFh ld (ix+3),00h ld (ix+4),2Eh ld (ix+5),02h ld (ix+6),02h ld (ix+7),0AAh ld (ix+8),0AAh ld hl,sha1_hash ld de,externalDataBuffer+9 ld bc,20 ldir ;Send the jig response data ld hl,externalDataBuffer ld b,8 sendRealJigResponseLoop: push bc ld b,8 ld c,01h push hl call SendInterruptData pop hl ld de,8 add hl,de pop bc djnz sendRealJigResponseLoop call WaitTimer20ms ld a,DONE jr SetJailbreakState $$: ld a,(jailbreakState) cp P3_WAIT_DISCONNECT jr nz,$F bit sentInterruptData,(iy+PS3JBFlags) jr nz,sentPort3Change ld a,(lastPortStatus) cp 03h jr nz,$F set sentInterruptData,(iy+PS3JBFlags) ld a,00001000b ld (hubIntResponse),a jr HandleJailbreakStateChanges sentPort3Change: ld a,(lastPortConnClear) cp 3 jr nz,$F call WaitTimer20ms ;Disconnect port 5 xor a call SwitchPort ld a,4 call DisconnectPort xor a ld (lastPortStatus),a ld a,P5_WAIT_DISCONNECT call SetJailbreakState res sentInterruptData,(iy+PS3JBFlags) jr HandleJailbreakStateChanges $$: ld a,(jailbreakState) cp P5_WAIT_DISCONNECT jr nz,$F bit sentInterruptData,(iy+PS3JBFlags) jr nz,sentPort5Change ld a,(lastPortStatus) cp 03h jr nz,sentPort5Change set sentInterruptData,(iy+PS3JBFlags) ld a,00100000b ld (hubIntResponse),a jr HandleJailbreakStateChanges sentPort5Change: ld a,(lastPortConnClear) cp 5 jr nz,$F call WaitTimer20ms ;Disconnect port 4 xor a call SwitchPort ld a,3 call DisconnectPort ld a,P4_WAIT_DISCONNECT call SetJailbreakState xor a ld (lastPortStatus),a res sentInterruptData,(iy+PS3JBFlags) jr HandleJailbreakStateChanges $$: ld a,(jailbreakState) cp P4_WAIT_DISCONNECT jr nz,$F bit sentInterruptData,(iy+PS3JBFlags) jr nz,sentPort4Change_1 ld a,(lastPortStatus) cp 05h jr nz,sentPort4Change_1 set sentInterruptData,(iy+PS3JBFlags) ld a,00010000b ld (hubIntResponse),a jr HandleJailbreakStateChanges sentPort4Change_1: ld a,(lastPortConnClear) cp 04h jr nz,$F call WaitTimer20ms ;Disconnect port 1 xor a call SwitchPort xor a call DisconnectPort ld a,P1_WAIT_DISCONNECT call SetJailbreakState res sentInterruptData,(iy+PS3JBFlags) xor a ld (lastPortStatus),a res lastStatusReceived,(iy+PS3JBFlags) jr HandleJailbreakStateChanges $$: ld a,(jailbreakState) cp P1_WAIT_DISCONNECT jr nz,$F bit sentInterruptData,(iy+PS3JBFlags) jr nz,sentPort1Change ld a,(lastPortStatus) cp 04h jr nz,sentPort1Change set sentInterruptData,(iy+PS3JBFlags) ld a,00000010b ld (hubIntResponse),a xor a ld (lastPortStatus),a jr HandleJailbreakStateChanges sentPort1Change: ld a,(lastPortConnClear) cp 01h jr nz,$F ld a,(lastPortStatus) cp 01h jr nz,$F bit lastStatusReceived,(iy+PS3JBFlags) jr nz,disconnectsDone xor a ld (lastPortStatus),a set lastStatusReceived,(iy+PS3JBFlags) ret disconnectsDone: call WaitTimer20ms call LoadPS3JBSettings bit 0,(iy+asm_Flag2) jr z,connectDevice6 ld a,DONE jr SetJailbreakState connectDevice6: ;Connect port 6 ld a,P6_WAIT_RESET call SetJailbreakState xor a ld (lastPortResetClear),a xor a call SwitchPort ld a,5 call ConnectPort in a,(8Eh) push af ld a,1 out (8Eh),a in a,(91h) and 0EFh or 40h out (91h),a pop af out (8Eh),a jr HandleJailbreakStateChanges $$: ld a,(jailbreakState) cp P6_WAIT_RESET jr nz,$F ld a,(lastPortResetClear) cp 6 jr nz,$F ;See if we have a stage2 payload, which will drive which device 6 descriptor to use ld hl,Stage2VarName rst 20h B_CALL ChkFindSym jr c,noStage2Payload set useStage2Payload,(iy+PS3JBFlags) ex de,hl ld a,b or a jr z,stage2InRAM ld de,9 call BHL_plus_DE call myLoadCIndPaged ld d,0 ld e,c call BHL_plus_DE stage2InRAM: ;BHL points to the AppVar's size bytes ld a,b ld (tempPage),a ld (tempAddress),hl noStage2Payload: ;Time to switch the address and start listening to device 6 ld a,6 call SwitchPort bit useStage2Payload,(iy+PS3JBFlags) ld hl,Device6DeviceDescriptor jr z,useDevice6Desc ld hl,AsbestOSDeviceDescriptor useDevice6Desc: ld (deviceDescAddress),hl call SetMaxPacketSize ld hl,Device6ConfigDescriptor ld (configDescAddress),hl res useShortConfigDesc,(iy+PS3JBFlags) ld a,P6_WAIT_ENUMERATE call SetJailbreakState jr HandleJailbreakStateChanges $$: ret ;USB Activity Hook ;-------------------------------------------------------------------------------------------------- USBactivityHook: add a,e in a,(80h) LOG Custom,a in a,(55h) ld b,a in a,(56h) LOG Interrupt,b LOG Interrupt,a or a jr z,skipPort56h ;Port 56h has the event bit 6,a jr nz,BcablePluggedIn bit 4,a jr nz,cancelUSBHook ;A cable plugged in bit 5,a jr nz,cancelUSBHook ;A cable unplugged bit 7,a jr z,$F ;B cable unplugged, kill USB device as peripheral call RecycleUSB jr cancelUSBHook $$: bit 1,a jr z,skipPort56h ;1,(56h) was set call InitializePeriphUSB jr nc,cancelUSBHook LOG Custom,04h jr cancelUSBHook bit0Port56hSet: ;I have absolutely no idea what 0,(56h) being set means, and we will never know. ;I go ahead and re-initialize just because, though. Who knows, it might actually do the right thing. LOG Bit0Port56,a call InitializePeriphUSB jr cancelUSBHook skipPort56h: in a,(56h) bit 0,a jr nz,bit0Port56hSet in a,(55h) ld b,a and 11h xor 11h jr z,cancelUSBHook bit 4,b jr z,readData di ;I may or may not actually care about this flag. bit 3,(iy+41h) jr nz,cancelUSBHook in a,(8Fh) bit 7,a jr nz,killUSBInterruptDisableError $$: xor a out (5Bh),a ld a,20h out (57h),a jr killUSBError bit0Port86hSet: in a,(8Fh) bit 7,a jr z,$B killUSBInterruptDisableError: xor a out (5Bh),a killUSBError: call unknownOutputs in a,(4Dh) bit 5,a jr nz,$F ld de,0FFFFh smallLoop: dec de ld a,d or e jr z,scfeiUSBError in a,(4Dh) bit 7,a jr z,smallLoop in a,(4Dh) bit 0,a jr z,smallLoop ld a,22h out (57h),a jr cancelUSBHook $$: in a,(4Dh) bit 6,a jr nz,$F xor a out (4Ch),a ld a,50h jr outPort57h $$: ld a,93h outPort57h: out (57h),a jr cancelUSBHook unknownOutputs: in a,(4Dh) bit 5,a jr nz,$F xor a res 6,(iy+41h) jr port54h39hOutput $$: ld b,8 in a,(4Dh) bit 6,a jr nz,$F ld b,0 $$: ld a,b out (4Ch),a port54h39hOutput: ld a,2 out (54h),a in a,(39h) and 0F8h out (39h),a ret scfeiUSBError: scf ei ld a,1 out (5Bh),a res 0,(iy+41h) jr cancelUSBHook ;Not sure whether this should run or not ld b,50 call WaitTimerBms LOG Custom,3 ;*** TESTING ei ld a,1 out (5Bh),a res 0,(iy+41h) jr cancelUSBHook BcablePluggedIn: LOG PeriphInit,0 call InitJailbreakMemory call LoadPS3JBSettings ld a,(apdTimerValue) ld (apdTimer),a call InitializePeriphUSB bit onRunning,(iy+onFlags) jr nz,cancelUSBHook ld a,03h out (10h),a B_JUMP Mon readData: di bit 0,(iy+41h) jr nz,cancelUSBHook in a,(8Fh) LOG IntPort8F,a ;*** TESTING in a,(86h) ld b,a LOG IntPort86,a ;*** TESTING bit 2,a jr nz,enableControlOutput in a,(82h) LOG IntPort82,a ;*** TESTING bit 0,a jr nz,controlDataReady in a,(84h) LOG IntPort84,a bit 2,a jr nz,interruptDataReady bit 1,a jr nz,interruptDataReady bit 0,b jr nz,bit0Port86hSet LOG Custom,2 ;*** TESTING ;Try to acknowledge USB interrupts, maybe this helps (it doesn't...) in a,(57h) ld b,a xor a out (57h),a ld a,b out (57h),a jr cancelUSBHook ;*** INCOMPLETE - some sort of data enableControlOutput: LOG EnableOut,0 xor a ld (9C86h),a ld a,1 out (5Bh),a in a,(87h) or 1 out (87h),a jr cancelUSBHook controlDataReady: xor a out (8Eh),a in a,(91h) LOG ControlData,a ; cp 5 ;*** HACK: I have no idea why this is suddenly necessary...(or is it?) ; jr z,receiveControlPacket ; ld b,a and 4 jr z,$F ld a,b and 0FBh out (91h),a jr cancelUSBHook $$: ld a,b and 10h jr z,$F ld a,b or 80h out (91h),a $$: ld a,b and 1 jr nz,receiveControlPacket ld hl,USBflag bit setAddress,(hl) jr z,cancelUSBHook ;this should never happen (but apparently it does, OS ignores it) res setAddress,(hl) ld a,(USBaddress) LOG SetAddress,a call SetDeviceAddress jr cancelUSBHook receiveControlPacket: ld hl,inputBuffer ld b,8 call GetControlPacket ld a,(inputBuffer) LOG ControlData,a cp 10100000b jr z,deviceToHostClassRequestReceived cp 0C0h jr z,asbestOSRequestReceived cp 40h jr z,asbestOSRequestReceived cp 80h jr z,deviceToHostReceived cp 81h jr z,deviceToHostReceived cp 02h jr z,endpointPacketReceived or a jr z,hostToDeviceReceived cp 01h jr z,hostToDeviceInterfaceReceived cp 00100011b jr z,otherClassRequestReceived cp 10100011b jr z,otherClassRequestReceived cp 21h jr nz,stallControlPipeEndHook ld a,(inputBuffer+1) cp 0AAh jr nz,stallControlPipeEndHook ;PS3 confirmation! All done! call WaitTimer20ms ld a,DONE call SetJailbreakState jr finishControlRequest stallControlPipeEndHook: ld hl,inputBuffer ld de,statVars+100h ld bc,8 ldir LOG IStallPipe,0 xor a out (8Eh),a ld a,60h out (91h),a cancelUSBHook: call HandleJailbreakStateChanges ;Acknowledge any USB interrupts (doesn't work, despite the OS having such unused code) ; in a,(57h) ; ld b,a ; xor a ; out (57h),a ; ld a,0FFh ;b ;enable everything ; out (57h),a ld b,0 ret exitUSBHook: ld b,2Ch ret ;-------------------------------------------------------------------------------------------------- ;Control Requests ;-------------------------------------------------------------------------------------------------- asbestOSRequestReceived: ld a,(inputBuffer+1) dec a ;1 jr z,asbestOSPrintReceived dec a ;2 jr z,asbestOSGetStage2SizeReceived dec a ;3 jr z,asbestOSReadStage2BlockReceived jr stallControlPipeEndHook hostToDeviceInterfaceReceived: ld a,(inputBuffer+1) cp 0Bh jr z,setInterfaceReceived LOG UnknownInterfaceRequest,a jr stallControlPipeEndHook otherClassRequestReceived: ld a,(inputBuffer+1) cp 03h jr z,hubSetFeatureReceived cp 01h jr z,hubClearFeatureReceived or a jr z,getHubStatusReceived LOG UnknownClassRequest,a jr stallControlPipeEndHook deviceToHostClassRequestReceived: ld a,(inputBuffer+1) or a jr z,getHubStatusReceived cp 06h ;GET_DESCRIPTOR jr z,getHubDescriptorReceived LOG UnknownDescriptor,a jr stallControlPipeEndHook endpointPacketReceived: ld a,(inputBuffer+1) cp 1 jr z,clearFeatureEndpoint cp 3 jr z,setFeatureEndpoint LOG UnknownDescriptor,a jr stallControlPipeEndHook deviceToHostReceived: ld a,(inputBuffer+1) or a jr z,getStatusReceived cp 06h jr z,getDescriptorReceived LOG UnknownDescriptor,a jr stallControlPipeEndHook hostToDeviceReceived: ld a,(inputBuffer+1) cp 05h jr z,setAddressReceived cp 09h jr z,setConfigurationReceived cp 03h jr z,setFeatureReceived dec a jr z,$F LOG UnknownDescriptor,a jr stallControlPipeEndHook $$: ;Clear feature received jr finishControlRequest setFeatureReceived: jr finishControlRequest classSpecificRequestReceived: ld a,(inputBuffer+1) cp 0Ah jr z,setIdleRequest cp 09h jr z,setReportRequest LOG UnknownDescriptor,a jr stallControlPipeEndHook asbestOSPrintReceived: xor a out (8Eh),a ld a,40h out (91h),a call WaitPort82 ld bc,(inputBuffer+6) ;Receive BC bytes from the control pipe to DE ld de,appData aospInputLoop: ld hl,maxPacketSize ld b,(hl) ld a,(inputBuffer+6+1) or a jr nz,aospInputBig ld a,(inputBuffer+6) cp b jr z,$F jr c,$F aospInputBig: ld hl,(inputBuffer+6) ld bc,(maxPacketSize) ld b,0 or a sbc hl,bc ld (inputBuffer+6),hl ld b,c jr aospInputContinue $$: ld b,a ld hl,0 ld (inputBuffer+6),hl aospInputContinue: $$: in a,(0A0h) ld (de),a inc de djnz $B ld hl,(inputBuffer+6) ld a,h or l jr z,finishControlRequest xor a out (8Eh),a ld a,2 out (91h),a call WaitPort82 jr aospInputLoop asbestOSGetStage2SizeReceived: xor a out (8Eh),a ld a,40h out (91h),a call DelayPort82 ld a,(tempPage) ld b,a ld hl,(tempAddress) call myLoadDEIndPaged xor a out (0A0h),a out (0A0h),a ld a,d out (0A0h),a ld a,e out (0A0h),a ld (tempAddress),hl ld a,b ld (tempPage),a jr finishControlOutput asbestOSReadStage2BlockReceived: xor a out (8Eh),a ld a,40h out (91h),a call DelayPort82 ld a,(tempPage) ld hl,(tempAddress) push af push hl ;Shift the offset/index so we know which block to send ld de,(inputBuffer+4) ld b,12 $$: sla e rl d djnz $B ld a,(tempPage) ld b,a ld hl,(tempAddress) call BHL_plus_DE ld a,b ld (tempPage),a ld (tempAddress),hl aosrOutputLoop: ld hl,maxPacketSize ld b,(hl) ld a,(inputBuffer+6+1) or a jr nz,aosrOutputBig ld a,(inputBuffer+6) cp b jr z,$F jr c,$F aosrOutputBig: ld hl,(inputBuffer+6) ld bc,(maxPacketSize) ld b,0 or a sbc hl,bc ld (inputBuffer+6),hl ld b,c jr aosrOutputContinue $$: ld b,a ld hl,0 ld (inputBuffer+6),hl aosrOutputContinue: ld hl,(tempAddress) ld a,(tempPage) $$: push bc ld b,a call myLoadCIndPaged ld a,c out (0A0h),a ld a,b pop bc djnz $B ld (tempPage),a ld (tempAddress),hl ld hl,(inputBuffer+6) ld a,h or l jr z,aosrDone xor a out (8Eh),a ld a,2 out (91h),a call DelayPort82 jr aosrOutputLoop jr finishControlRequest aosrDone: pop hl pop af ld (tempPage),a ld (tempAddress),hl jr finishControlOutput setInterfaceReceived: ld a,(inputBuffer+4) LOG SetInterface,a jr finishControlRequest hubClearFeatureReceived: ld a,(inputBuffer+2) cp 16 jr z,$F cp 17 jr z,$F cp 18 jr z,$F cp 19 jr z,$F cp 20 jr z,$F ;Not acknowledging a status change jr finishControlRequest $$: ld a,(inputBuffer+4) dec a ld b,0 ld c,a ld hl,deviceChangedBitmap add hl,bc add hl,bc ld a,(inputBuffer+2) cp 16 jr nz,$F ld bc,1111111111111110b ld a,(inputBuffer+4) ld (lastPortConnClear),a jr hubClearFeatureContinue $$: ld bc,1111111111111110b cp 17 jr z,hubClearFeatureContinue ld bc,1111111111111011b cp 18 jr z,hubClearFeatureContinue ld bc,1111111111110111b cp 19 jr z,hubClearFeatureContinue ld bc,1111111111101111b ld a,(inputBuffer+4) ld (lastPortResetClear),a hubClearFeatureContinue: ;BC is mask to clear against ld a,(hl) and c ld (hl),a inc hl ld a,(hl) and b ld (hl),a jr finishControlRequest hubSetFeatureReceived: ld a,(inputBuffer+4) dec a ld b,0 ld c,a ld hl,deviceChangedBitmap add hl,bc add hl,bc ld a,(inputBuffer+2) ld bc,00010000b cp 04h jr z,hubSetFeatureContinue ld bc,00000000b cp 08h jr nz,$F ld a,(inputBuffer+4) cp 6 jr nz,finishControlRequest ld a,HUB_READY call SetJailbreakState jr finishControlRequest $$: ld c,00000000b ;C is mask to set against hubSetFeatureContinue: ld a,(hl) or c ld (hl),a inc hl ld a,(hl) or b ld (hl),a ld d,1 ld a,(inputBuffer+4) $$: sla d dec a jr nz,$B ld a,d ld (hubIntResponse),a jr finishControlRequest finishControlOutput: xor a out (8Eh),a ld a,0Ah out (91h),a call WaitPort82 call WaitPort82 call WaitTimer20ms call WaitTimer20ms call WaitTimer20ms jr cancelUSBHook getStatusReceived: xor a out (8Eh),a ld a,40h out (91h),a ld a,1 out (0A0h),a xor a out (0A0h),a jr finishControlOutput clearFeatureEndpoint: ;Something is telling the calculator to clear the halt condition on an endpoint (I think this might also reset data toggle) ld a,(inputBuffer+4) and 7Fh ld (USBaddress),a ld a,(inputBuffer+4) and 80h ld (USBaddress+1),a in a,(8Eh) push af ld a,(USBaddress) out (8Eh),a ld a,(USBaddress+1) or a jr z,$F in a,(91h) and 0EFh or 40h out (91h),a jr endpointReceivedDone $$: in a,(94h) and 0DFh or 80h out (94h),a endpointReceivedDone: pop af out (8Eh),a jr finishControlRequest getHubStatusReceived: ld a,(inputBuffer+4) ld (lastPortStatus),a xor a out (8Eh),a ld a,40h out (91h),a ld hl,0 ld a,(inputBuffer+4) or a jr z,$F ;Set port status information in HL ld hl,deviceBitmap ld a,(inputBuffer+4) dec a ld c,a ld b,0 add hl,bc add hl,bc ld e,(hl) inc hl ld d,(hl) ex de,hl $$: ld a,l out (0A0h),a ld a,h out (0A0h),a ld hl,0 ld a,(inputBuffer+4) or a jr z,$F ;Set port change information in HL ld hl,deviceChangedBitmap ld a,(inputBuffer+4) dec a ld c,a ld b,0 add hl,bc add hl,bc ld e,(hl) inc hl ld d,(hl) ex de,hl $$: ld a,l out (0A0h),a ld a,h out (0A0h),a jr finishControlOutput setFeatureEndpoint: ;Something is telling the calculator to halt an endpoint. ld a,(inputBuffer+4) and 7Fh ld (USBaddress),a ld a,(inputBuffer+4) and 80h ld (USBaddress+1),a in a,(8Eh) push af ld a,(USBaddress) out (8Eh),a ld a,(USBaddress+1) or a jr nz,$F ld a,10h out (91h),a jr endpointReceivedDone $$: ld a,20h out (91h),a jr endpointReceivedDone setReportRequest: xor a out (8Eh),a ld a,40h out (91h),a ld de,0FFFFh $$: dec de ld a,d or e jr z,stallControlPipeEndHook in a,(82h) and 1 jr z,$B in a,(91h) and 1 jr z,stallControlPipeEndHook in a,(96h) dec a jr nz,stallControlPipeEndHook in a,(0A0h) ;this is probably 01, don't really care either way jr finishControlRequest setConfigurationReceived: LOG SetConfig,0 ld a,1 out (8Eh),a xor a call SetupInPipe ld a,2 out (8Eh),a ld a,1 call SetupOutPipe xor a ld (bytesRemaining),a jr finishControlRequest setAddressReceived: ld a,(inputBuffer+2) LOG GotSetAddr,a ld (USBaddress),a ld hl,USBflag set setAddress,(hl) ld a,1 out (5Bh),a ld a,7Fh out (87h),a ld a,0Eh out (89h),a jr finishControlRequest getHubDescriptorReceived: LOG ReadDescriptor,29h ld a,(inputBuffer+6) ld h,0 ld l,a ld (descSize),hl ld de,hubDescriptor ld a,(de) ld h,0 ld l,a ld bc,(descSize) or a push hl sbc hl,bc pop hl jr nc,startReceivingDescriptor ld (descSize),hl jr startReceivingDescriptor hubDescriptor: DB 09h DB 29h DB 06h DW 00A9h DB 00h ;32h DB 64h DB 00h DB 0FFh getDescriptorReceived: ld a,(inputBuffer+3) LOG ReadDescriptor,a dec a ;cp 01h jr z,deviceDescriptorReceived dec a ;cp 02h jr z,configDescriptorReceived dec a ;cp 03h jr z,stringDescriptorReceived jr stallControlPipeEndHook stringDescriptorReceived: ld a,(inputBuffer+2) LOG StringDesc,a ;Um...just freak out jr stallControlPipeEndHook ; or a ; ld de,stringDescriptor ; jr z,descriptorReceived ; dec a ; ld de,manufacturerString ; jr z,descriptorReceived ; dec a ; jr nz,stallControlPipeEndHook ; ld de,productString ; in a,(21h) ; and 3 ; jr z,descriptorReceived ; ld de,productStringSE ; jr descriptorReceived configDescriptorReceived: ;This is really horrible. ld a,(portCur) cp 1 jr nz,$F jr SendDevice1ConfigDescriptor $$: ld a,(portCur) cp 2 jr nz,$F ld hl,(inputBuffer+6) ld de,8 or a sbc hl,de jr z,$F ld a,P2_READY call SetJailbreakState jr startConfigDescriptor $$: ld a,(portCur) cp 3 jr z,SendDevice3ConfigDescriptor cp 4 jr z,SendDevice4ConfigDescriptor startConfigDescriptor: ld hl,(inputBuffer+6) ld (descSize),hl ;Are we using a separate packet for the config descriptor? If not, skip this step bit useShortConfigDesc,(iy+PS3JBFlags) jr z,$F push hl ld de,8 or a sbc hl,de pop hl jr z,$F ;This is a special config descriptor packet larger than 8 bytes, so set a different size ld hl,0F00h ld (descSizeOverride),hl set overrideSize,(iy+PS3JBFlags) $$: ld de,(configDescAddress) bit useShortConfigDesc,(iy+PS3JBFlags) jr z,$F ld hl,(descSize) push hl push de ld de,8 or a sbc hl,de pop de pop hl jr nz,$F ;Size is 8, do we use the short descriptor or the big one? ld hl,8 ld (descSizeOverride),hl set overrideSize,(iy+PS3JBFlags) ld de,(shortConfigDescAddress) $$: inc de inc de ld a,(de) ld l,a inc de ld a,(de) ld h,a dec de dec de dec de ld bc,(descSize) or a push hl sbc hl,bc pop hl jr nc,$F ld (descSize),hl jr $F deviceDescriptorReceived: ld de,(deviceDescAddress) descriptorReceived: ld hl,(inputBuffer+6) ld (descSize),hl push de ld de,8 or a sbc hl,de pop de jr z,startReceivingDescriptor ld a,(de) ld h,0 ld l,a ld (descSize),hl startReceivingDescriptor: $$: bit overrideSize,(iy+PS3JBFlags) res overrideSize,(iy+PS3JBFlags) jr z,$F ld hl,(descSizeOverride) ld (descSize),hl $$: LOG Custom,0FAh ld hl,(descSize) LOG Custom,h LOG Custom,l xor a out (8Eh),a ld a,40h out (91h),a call DelayPort82 ld a,1 out (20h),a di descriptorOutLoop: ld hl,maxPacketSize ld b,(hl) ld a,(descSize+1) or a jr nz,descriptorOutBig ld a,(descSize) cp b jr c,$F descriptorOutBig: ld hl,(descSize) ld bc,(maxPacketSize) ld b,0 or a sbc hl,bc ld (descSize),hl ld b,c jr continueOutput $$: ld b,a ld hl,0 ld (descSize),hl continueOutput: $$: LOG DataStart,b bit noDataLog,(iy+PS3JBFlags) jr z,$F LOG DataStart,b $$: ld a,(de) LOG Data,a bit noDataLog,(iy+PS3JBFlags) jr z,gdNoLog LOG Data,a gdNoLog: out (0A0h),a inc de djnz $B LOG DataEnd,b bit noDataLog,(iy+PS3JBFlags) jr z,$F LOG DataEnd,b $$: ld hl,(descSize) ld a,h or l jr nz,$F res noDataLog,(iy+PS3JBFlags) ld a,(portCur) cp 5 jr nz,finishControlOutput ld a,1 out (8Eh),a ld a,1 call SetupOutPipe ld a,2 out (8Eh),a ld a,1 call SetupInPipe jr finishControlOutput $$: ;in a,(91h) LOG IntPort91,a xor a out (8Eh),a ld a,2 out (91h),a call DelayPort82 jr descriptorOutLoop setIdleRequest: finishControlRequest: xor a out (8Eh),a in a,(91h) ld a,48h out (91h),a in a,(91h) jr cancelUSBHook DelayPort82: push bc ld bc,08FFh $$: in a,(82h) bit 0,a jr nz,$F ex hl,(sp) ex hl,(sp) dec bc ld a,b or c jr nz,$B $$: pop bc ret ;-------------------------------------------------------------------------------------------------- ;Interrupt Requests ;-------------------------------------------------------------------------------------------------- interruptDataReady: ld a,2 out (8Eh),a in a,(94h) bit 2,a jr nz,interruptDataNAKStall bit 4,a jr nz,interruptDataNAKStall set 5,(iy+41h) xor a ld (bytesRemaining),a ;Interrupt data, receive it and go di ld hl,jigChallengeData ld a,(jigBytesReceived) ld b,0 ld c,a add hl,bc ld b,8 call ReceiveInterruptData jr c,cancelUSBHook ld a,(jigBytesReceived) add a,8 ld (jigBytesReceived),a jr cancelUSBHook interruptDataNAKStall: ;Do something about this? jr cancelUSBHook ;-------------------------------------------------------------------------------------------------- jigResponse: DB 080h, 000h, 000h, 000h, 000h, 03Dh, 0EEh, 078h, 080h, 000h, 000h, 000h, 000h, 03Dh, 0EEh, 088h DB 080h, 000h, 000h, 000h, 000h, 033h, 0E7h, 020h, 0E8h, 083h, 0FFh, 0F0h, 0E8h, 063h, 0FFh, 0F8h DB 0E8h, 0A3h, 000h, 018h, 038h, 063h, 010h, 000h, 07Ch, 004h, 028h, 000h, 040h, 082h, 0FFh, 0F4h DB 038h, 0C3h, 0F0h, 020h, 07Ch, 0C9h, 003h, 0A6h, 04Eh, 080h, 004h, 020h, 004h, 000h, 000h, 000h