Skip to content

Add USB syscalls#87

Merged
tari merged 3 commits intoJonimoose:masterfrom
Heath123:usb_syscalls
Jan 17, 2023
Merged

Add USB syscalls#87
tari merged 3 commits intoJonimoose:masterfrom
Heath123:usb_syscalls

Conversation

@Heath123
Copy link
Copy Markdown
Contributor

@Heath123 Heath123 commented Jan 14, 2023

These are direct equivalents to the serial syscalls, but communicate over USB bulk transfer instead (not protocol 7, just raw data).

I found these by decompiling the Comm syscalls in Ghidra, which makes it very obvious that these are direct equivalents, e.g.:
image

Not all of them are tested, but I have gotten basic two-way communication working with libusb. The usage on the calculator side looks something like:

USB_Open(0x20);
USB_ClearRX();

USB_Write((unsigned char *) "Hello World!", 13);

// Wait for response
while (USB_PollRX() == 0) {
  // This is close to how the OS's USB functions wait
  OS_InnerWait_ms(25); // Wait 25ms
}

char buf[102];
buf[0] = '-';
buf[1] = '-';
// Receive a message and print it
short count;
USB_Read((unsigned char *) buf + 2, 100, &count);
Bdisp_AllClr_VRAM();
PrintXY(1, 1, buf, 0, COLOR_BLACK);
int key;
GetKey(&key);

USB_Close();

This doesn't seem properly close the connection because I can't connect again after, so I still need to work that part out

@dr-carlos
Copy link
Copy Markdown
Contributor

Looks great!
Thanks for doing this research.

@Heath123
Copy link
Copy Markdown
Contributor Author

Example of what you can use this for: a PC->calculator screen mirroring tool! (like the reverse of the screen receiver mode)

https://cdn.discordapp.com/attachments/1032462478577238076/1063932759204188240/VID_20230114_2126178512.mp4

@dr-carlos
Copy link
Copy Markdown
Contributor

dr-carlos commented Jan 15, 2023

Hello,
Regarding your USB_Close commit, I'm not sure USB_Close does take a parameter.
I'm probably wrong, but here is the disassembly:

<%1350 USB_Close>
 801edd4a:  4f22   sts.l   pr, @-r15
 801edd4c:  d627   mov.l   0xfd801dc0, r6
 801edd4e:  6061   mov.w   @r6, r0
 801edd50:  8801   cmp/eq  #1, r0
 801edd52:  8901   bt      <0x801edd58>
 801edd54:  a004   bra     <0x801edd60>
 801edd56:  e005   mov     #5, r0
 801edd58:  d22d   mov.l   %1eef, r2
 801edd5a:  420b   jsr     @r2
 801edd5c:  e401   mov     #1, r4    // r4 (the first parameter) is overwritten when running Syscall 0x1EEF, so it was never used.
 801edd5e:  e000   mov     #0, r0
 801edd60:  4f26   lds.l   @r15+, pr
 801edd62:  000b   rts
 801edd64:  0009   nop

It appears to me that mode (r4) is never used and thus isn't a parameter.

What do you think? I'd be interested to know why you added the parameter.

By the way, your screen mirroring tool is really cool. Could I see the source code?

@Heath123
Copy link
Copy Markdown
Contributor Author

Heath123 commented Jan 15, 2023

Hello, Regarding your USB_Close commit, I'm not sure USB_Close does take a parameter. I'm probably wrong, but here is the disassembly:

<%1350 USB_Close>
 801edd4a:  4f22   sts.l   pr, @-r15
 801edd4c:  d627   mov.l   0xfd801dc0, r6
 801edd4e:  6061   mov.w   @r6, r0
 801edd50:  8801   cmp/eq  #1, r0
 801edd52:  8901   bt      <0x801edd58>
 801edd54:  a004   bra     <0x801edd60>
 801edd56:  e005   mov     #5, r0
 801edd58:  d22d   mov.l   %1eef, r2
 801edd5a:  420b   jsr     @r2
 801edd5c:  e401   mov     #1, r4    // r4 (the first parameter) is overwritten when running Syscall 0x1EEF, so it was never used.
 801edd5e:  e000   mov     #0, r0
 801edd60:  4f26   lds.l   @r15+, pr
 801edd62:  000b   rts
 801edd64:  0009   nop

It appears to me that mode (r4) is never used and thus isn't a parameter.

What do you think? I'd be interested to know why you added the parameter.

I assumed that it was the same as the serial syscall, and Ghidra was showing one in the function call, but Ghidra gets it wrong sometimes so I can revert that if it doesn't take one. I haven't looked much at these syscalls or tested all of them, so some other others be wrong as well, but everything I've tried to use so far seems to work

By the way, your screen mirroring tool is really cool. Could I see the source code?

Thanks, it's not really ready yet but this is what I have so far on the calculator side if you want to see the basic gist (no pun intended) of how it works:

https://gist.github.com/Heath123/cae5040a9bd9f13c448324601ba01544

This version is a bit outdated has a bug where it always sends 0 for the keypress because it's trying to send the first byte of an int but that's easy to fix by changing the type to unsigned char

I'll publish the PC side at some point, it's currently only working with Linux on X11 though

If you're interested I'm also working on a tool to bypass the flash memory and push addins directly to the CG50's extended RAM then jump to them which should make testing a lot faster:
https://media.discordapp.net/attachments/1032462478577238076/1064190814521139351/VID_20230115_1432154522.mp4

@Heath123
Copy link
Copy Markdown
Contributor Author

Heath123 commented Jan 15, 2023

I should probably add the Comm syscalls too (most of them are missing currently), they're slightly higher level I think so they might be easier to use

@dr-carlos
Copy link
Copy Markdown
Contributor

I assumed that it was the same as the serial syscall, and Ghidra was showing one in the function call, but Ghidra gets it wrong sometimes so I can revert that if it doesn't take one. I haven't looked much at these syscalls or tested all of them, so some other others be wrong as well, but everything I've tried to use so far seems to work

That would make sense, but it appears that Comm_Close only passes the mode to Serial_Close.

Thanks, it's not really ready yet but this is what I have so far on the calculator side if you want to see the basic gist (no pun intended) of how it works:

https://gist.github.com/Heath123/cae5040a9bd9f13c448324601ba01544

This version is a bit outdated has a bug where it always sends 0 for the keypress because it's trying to send the first byte of an int but that's easy to fix by changing the type to unsigned char

I'll publish the PC side at some point, it's currently only working with Linux on X11 though

If you're interested I'm also working on a tool to bypass the flash memory and push addins directly to the CG50's extended RAM then jump to them which should make testing a lot faster: https://media.discordapp.net/attachments/1032462478577238076/1064190814521139351/VID_20230115_1432154522.mp4

That is great! I'm sure the people at Cemetech would love to use these when they're finished.

I should probably add the Comm syscalls too (most of them are missing currently), they're slightly higher level I think so they might be easier to use

Yep, makes sense.

@tari tari merged commit 297a62b into Jonimoose:master Jan 17, 2023
@Heath123 Heath123 deleted the usb_syscalls branch January 17, 2023 09:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants