;---------------------------------------------------------------------------- ;InitializePeriphUSB: ;Initializes ourself as a USB peripheral connected to...something. ;Inputs: None ;Outputs: Carry flag set if any issues. InitializePeriphUSB: bcall(810Eh) ;_KillUSB ret c ld a,80h out (57h),a xor a out (4Ch),a ld a,1 out (5Bh),a xor a in a,(4Ch) ld a,2 out (54h),a ld a,20h out (4Ah),a xor a out (4Bh),a in a,(3Ah) bit 3,a jr z,port3AhReset1 ld a,20h out (4Bh),a port3AhReset1: xor a out (54h),a ld a,42h out (36h),a xor a out (37h),a ld a,1 out (38h),a timerWait: in a,(4) bit 7,a jr z,timerWait in a,(3Ah) bit 3,a jr z,port3AhReset2 ld a,44h out (54h),a port3AhReset2: ld a,0C4h out (54h),a ld a,8 out (4Ch),a ld de,0FFFFh port5AhLoop: dec de ld a,d or e scf ret z in a,(4Ch) cp 1Ah jr z,port5AhDone cp 5Ah jr nz,port5AhLoop port5AhDone: ld a,0FFh out (87h),a xor a out (92h),a in a,(87h) ld a,0Eh out (89h),a ld a,5 out (8Bh),a in a,(81h) or out (81h),a in a,(54h) or 1 out (54h),a ld b,5 frameCounterLoop: ld de,0FFFFh frameCounterLoop2: dec de ld a,d or e jr z,counterExpired in a,(8Ch) or a jr z,frameCounterLoop2 ret counterExpired: djnz frameCounterLoop scf ret ;---------------------------------------------------------------------------- ;IsUSBAvailable: ;Returns whether USB communication MAY be available. ;Inputs: None ;Outputs: Carry flag set if USB is not available. IsUSBAvailable: in a,(2) bit 5,a scf ret z ld a,(4Dh) or a bit 5,a ret z bit 6,a scf ret nz ccf ret ;---------------------------------------------------------------------------- ;SendUSBData: ;Sends data over USB. ;Inputs: HL => pointer in zone 1 (RAM pages 3\2) of data to send. ; DE: number of bytes to send. ;Outputs: DE bytes sent from HL. ; Carry flag set if any issues. SendUSBData: res 0,(iy+43h) bcall(50F2h) res 0,(iy+41h) res 5,(iy+41h) ret ;---------------------------------------------------------------------------- ;ReceiveUSBDataWait: ;Receives data over USB (waits until data is received). ;Inputs: HL => pointer in RAM to store data to. ; BC: number of bytes to receive. ;Outputs: BC bytes received to HL. ; Carry flag set if any issues. ;Make sure you know how much you need to be receiving before calling. ;This is a blocking call and will not return until everything is received. ReceiveUSBDataWait: ei halt in a,(4) bit 3,a scf ret z bit 5,(iy+41h) jr z,ReceiveUSBDataWait ;---------------------------------------------------------------------------- ;ReceiveUSBData: ;Receives data over USB. ;Inputs: 5,(iy+41h) set by OS. ; HL => pointer in RAM to store data to. ; BC: number of bytes to receive. ;Outputs: BC bytes received to HL. ; Carry flag set if any issues. ;Make sure you know how much you need to be receiving before calling. ReceiveUSBData: push bc push af xor a ld (9834h),a jr receive_data_ready receive_big_loop: in a,(4) bit 3,a jr z,P2scfRet bit 5,(iy+41h) jr nz,receive_data_ready in a,(84h) bit 2,a jr nz,receiving_data bit 1,a jr z,restart_receive_loop receiving_data: set 5,(iy+41h) xor a ld (9C27h),a jr receive_data_ready restart_receive_loop: in a,(86h) bit 5,a jr nz,P2scfRet jr receive_big_loop receive_data_ready: push bc push hl ld hl,40h or a sbc hl,bc pop hl ld b,c jr nc,receiveRest ld b,40h receiveRest: call ReceiveUSBData_small ex de,hl pop hl jr c,P2scfRet or a ld b,0 sbc hl,bc jr z,P2ret ld b,h ld c,l ex de,hl jr receive_big_loop P2ret: pop bc ld a,b pop bc ret P2scfRet: pop af pop bc scf ret ReceiveUSBData_small: ld a,b or a ret z ld a,40h cp b ret c ld a,b ld (9C80h),a ld a,(9C27h) or a jr z,ReceiveUSBData_continue cp b jr nc,ReceiveUSBData_continue ld b,a ld (9C80h),a ReceiveUSBData_continue: in a,(8Fh) bit 2,a jp z,calcIsPeripheral xor a out (5Bh),a ld a,(9C27h) or a jr nz,startReceive ld a,1 out (8Eh),a ld a,21h out (9Ah),a xor a in a,(9Ah) ld a,8 out (93h),a xor a in a,(93h) ld a,0FFh out (89h),a xor a out (95h),a in a,(89h) ld a,0A1h out (8Bh),a in a,(94h) bit 2,a jp nz,receiveError bit 6,a jp nz,receiveError ld a,1 out (5Bh),a ld a,(9C27h) or a jr nz,startReceive ld a,1 out (8Eh),a in a,(94h) in a,(96h) startReceive: push af ld a,(9C80h) ld b,a ld c,0 receiveLoop: in a,(0A1h) ld (hl),a inc hl inc c djnz receiveLoop ld a,1 out (8Eh),a in a,(94h) bit 2,a jr nz,p1ReceiveError bit 6,a jr nz,p1ReceiveError pop af sub c ld (9C27h),a set 5,(iy+41h) ret nz ld a,1 out (8Eh),a ld a,21h out (9Ah),a ld a,8 out (93h),a xor a in a,(93h) ld a,0Eh out (89h),a xor a out (95h),a res 5,(iy+41h) xor a ld (9C27h),a res 0,(iy+41h) ld a,20h out (94h),a ld a,1 out (5Bh),a ret calcIsPeripheral: ld a,2 out (8Eh),a in a,(94h) bit 6,a jr z,startReceive2 and 0DFh out (94h),a pop af bcall(5257h) ;_KillUSBDevice jr receiveError startReceive2: ld a,(9C27h) or a jr nz,startReceive3 in a,(96h) startReceive3: push af ld c,0 receivePeriphLoop: in a,(0A2h) ld (hl),a inc hl inc c djnz receivePeriphLoop ld a,2 out (8Eh),a pop af sub c ld (9C27h),a ret nz xor a ld (9C27h),a in a,(94h) and 0FEh out (94h),a res 5,(iy+41h) ld a,0A1h ld (8Bh),a jr endReceive p1ReceiveError: pop af receiveError: res 5,(iy+41h) scf endReceive: ei ld a,1 out (5Bh),a res 0,(iy+41h) ret ;----------------------------------------------------------------------------