https://wikiti.brandonw.net/api.php?action=feedcontributions&user=Dan+Englender&feedformat=atomWikiTI - User contributions [en]2024-03-28T21:55:59ZUser contributionsMediaWiki 1.23.5https://wikiti.brandonw.net/index.php?title=Programming_an_OS_for_z80_calculatorsProgramming an OS for z80 calculators2013-04-25T21:11:31Z<p>Dan Englender: Undo revision 10094 by KermMartian (Talk) -- Editorial commentary not appropriate for informational article.</p>
<hr />
<div>It is now fairly easy for an intermediate to advanced z80 assembly programmer to write its own Operating System (from now on OS) for its calculator. Mainly because there is a lot of documentation floating about z80 calculators hardware, emulator and examples of OS.<br />
<br />
And now an OS can be very easily distributed and installed in .8xu format.<br />
<br />
== Main concerns before starting ==<br />
{{stub}}<br />
<br />
== Sample basic OS functionality ==<br />
<br />
Every OS needs these, just to boot:<br />
* Page 00 boot code<br />
* A valid OS header<br />
<br />
But if you want it to actually do anything useful, it needs to: <br />
* Initialize the LCD<br />
* Set up memory<br />
* Initialize the stack<br />
<br />
== Memory layout ==<br />
<br />
<br />
== Hardware ==<br />
<br />
== Tools for building the OS ==<br />
You really should get an adequate assembler. SPASM and Brass are well suited. But others may be used.<br />
You will also need a program to take the binary to convert into a .8xu file.<br />
http://www.ticalc.org/archives/files/fileinfo/383/38392.html<br />
<br />
Here is a script using spasm to assemble and sign the OS.<br />
<nowiki><br />
$ spasm main.asm main.bin<br />
$ <br />
</nowiki><br />
<br />
== Testing ==<br />
<br />
<br />
== See also ==<br />
* http://www.cemetech.net/forum/viewtopic.php?t=5008<br />
* other OSes source code<br />
* ports<br />
* (many more I will add)<br />
<br />
== Acknowledgements ==<br />
* SirCmpwn for initial topics on forums<br />
* Brandonw for giving more documentation about this<br />
* etc.</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=84PCSE:RAM:8B2284PCSE:RAM:8B222013-04-04T02:36:13Z<p>Dan Englender: You never know...</p>
<hr />
<div>[[Category:84PCSE:RAM:By Address|8B22 - asm_prgm_size]] [[Category:84PCSE:RAM:By Name|asm_prgm_size]]<br />
== Synopsis ==<br />
'''Unofficial Name:''' asm_prgm_size<br />
<br />
'''Memory Address:''' 8B22h<br />
<br />
'''Length:''' 2 bytes<br />
<br />
When an assembly program runs, this stores the size of the program so that the OS knows how much to delete after the program runs. If you're not running from a shell, after copying a stub to scrap RAM, you can use the value in this to delete yourself. Then you can _JForceCmdNoChar without leaking memory. But if you're running from a shell, you're likely to die horribly.</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=83Plus:Software:usb8x/Asm_Interface/Pad83Plus:Software:usb8x/Asm Interface/Pad2011-01-21T14:54:50Z<p>Dan Englender: Fixed links.</p>
<hr />
<div>The usb8x gamepad driver is compatible with some USB gamepad controllers. It will (probably) not work with most analog sticks, but will (probably) work with most D-Pads and buttons. The gamepad driver does not bind buttons to a particular function. In other words, it doesn't know that the "down" button means down. Unless you already know the appropriate button mappings for a particular gamepad (the mapping could be saved between program runs), you will have to prompt the user to map buttons with [[83Plus:Software:usb8x/Asm_Interface/Pad/PadSetup|PadSetup]].<br />
<br />
<br />
The gamepad driver is initialized via [[83Plus:Software:usb8x/Asm_Interface/Pad/PadInit|PadInit]]. This entry point initializes both the driver and the gamepad hardware, so you may want to check to see if a device is connected via [[83Plus:Software:usb8x/Asm_Interface/IsDeviceConnected|IsDeviceConnected]] first.<br />
<br />
<br />
After initializing the gamepad, use [[83Plus:Software:usb8x/Asm_Interface/Pad/PadSetup|PadSetup]] to help determine button mappings, unless you've already saved a previous mapping. Then use [[83Plus:Software:usb8x/Asm_Interface/Pad/PadStart|PadStart]] to start receiving gamepad data to your callback function. The callback will be passed raw data from the gamepad, and should use the masks it collected via PadSetup to determine which buttons have been pressed.<br />
<br />
== Entry Points ==<br />
{| border="1" cellpadding="2" cellspacing="0" <br />
|-<br />
| [[83Plus:Software:usb8x/Asm_Interface/Pad/PadInit|PadInit]] || Initialize gamepad driver and hardware<br />
|-<br />
| [[83Plus:Software:usb8x/Asm_Interface/Pad/PadSetup|PadSetup]] || Get offset and bitmask to detect a specific button (map buttons)<br />
|-<br />
| [[83Plus:Software:usb8x/Asm_Interface/Pad/PadStart|PadStart]] || Start sending gamepad data to the callback function<br />
|-<br />
| [[83Plus:Software:usb8x/Asm_Interface/Pad/PadVersion|PadVersion]] || Get driver version and RAM requirements<br />
|}</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=83Plus:Software:usb8x/Asm_Interface/Silver83Plus:Software:usb8x/Asm Interface/Silver2011-01-21T14:53:13Z<p>Dan Englender: Fixed links</p>
<hr />
<div>The SilverLink driver provides support for the TI-Graphlink SilverLink cable. This cable can be used to communicate with another calculator and to create, for example, a daisy-chain network of TI-84 Plus calculators.<br />
<br />
The SilverLink driver is initialized via [[83Plus:Software:usb8x/Asm_Interface/Silver/SilverInit|SilverInit]]. This entry point initializes both the driver and the silverlink hardware, so you may want to check to see if a device is connected via [[../IsDeviceConnected|IsDeviceConnected]] first.<br />
<br />
After initializing the SilverLink, use [[83Plus:Software:usb8x/Asm_Interface/Silver/SilverSend|SilverSend]] to send data to the connected device. Incoming data will be reported to the callback function specified during U_CALL_INIT.<br />
<br />
== Entry Points ==<br />
{| border="1" cellpadding="2" cellspacing="0" <br />
|-<br />
| [[83Plus:Software:usb8x/Asm_Interface/Silver/SilverInit|SilverInit]] || Initialize the SilverLink driver and hardware<br />
|-<br />
| [[83Plus:Software:usb8x/Asm_Interface/Silver/SilverSend|SilverSend]] || Send data via the SilverLink to the attached device<br />
|}</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=WikiTI_HomeWikiTI Home2009-01-31T23:12:25Z<p>Dan Englender: </p>
<hr />
<div>Welcome to WikiTI, a Wiki for programmers and hardware hackers of Texas Instruments's graphing calculators. WikiTI's goal is to serve as a central place for the discussion and exploration of the undocumented features of the TI-OS and hardware. To browse our documentation, you can click the "Calculator Documentation" link to the left.<br />
<br />
Any programmer or hacker is free to contribute any [[Calculator_Documentation|documentation]] of the TI-OS, even if the information is incomplete or possibly wrong. For more information, see our page on [[Contributing]]. Not sure where to start contributing? Check out the list of [[Special:Wantedpages|Wanted Pages]] that are linked to but don't yet exist, the list of [[:Category:Stubs|stub pages]] that need filled out, the list of [[:Category:Missing Information|pages with missing information]], and the list of [[:Category:Wikify|pages that need to be formatted]].<br />
<br />
== News ==<br />
<br />
* '''January 31, 2009 - ([[User:Brandonw|Brandon Wilson]]):''' I have moved WikiTI to my own host so that it could be upgraded with the latest version of MediaWiki, which should hopefully stop all the spam. Editing for registered users has finally been re-enabled, so get to it!<br />
* '''October 29, 2008 - ([[User:AndyJ|Andy Janata]]):''' In a further attempt to curb spam, I changed some more settings and now only admins can create pages (at least, I think that's what I did. Pretty sure it worked, but not 100%). Yes, it is rather extreme, but it's the only surefire way to stop all the new spam pages. A new host (with PHP5) would be prefered. I may go ahead and host it on my own site if no other solution can be found soon. In the mean time, if you would like to request a page be made, please drop a line on [[Talk:WikiTI Home|the home page's talk page]].<br />
* '''September 23, 2008 - ([[User:AndyJ|Andy Janata]]):''' Sorry for the long delay in updates. I have upgraded MediaWiki to the latest version that runs on PHP4. This, unfortunately, is already over a year old. Hopefully this will cut down on the spam a bit. If you find anything broken because up this update, please contact me at (ajanata) [AT] 'gmail' {FULLSTOP} &lt;com&gt;.<br />
:*I have promoted [[User:Brandonw|Brandon]] and [[User:FloppusMaximus|FloppusMaximus]] to sysops.<br />
:*Everybody must confirm their email address (if they haven't done so already) to edit pages, for real this time. This may have worked in the past, but it was quite clearly not workign when I was testing.<br />
:*New users may not create new pages, even after verifying their email address, for 4 days. If this is too much a nuisance, I can reduce the time, but I do not wish to eliminate it at this time.<br />
* '''March 13, 2006 - ([[User:Dan Englender|Dan Englender]]):''' To help reduce spam, you must now [[Special:Confirmemail|confirm your email]] address once before editing any pages. You should only have to do this once. If you have any problems with this feature please email wikiti AT mail DOT denglend DOT net. Sorry for any inconvenience.<br />
* '''March 13, 2006 - ([[User:Dan Englender|Dan Englender]]):''' WikiTI has been upgraded from MediaWiki 1.4.0 to 1.5.7 for security concerns and new features. If you find anything that doesn't work like it used to, please make a note on the discussion page and bear with us as we try to fix everything.<br />
<font size=-2>[[Old_News|(Old News)]]</font><br />
== Contacting the WikiTI Administration ==<br />
If you wish to contact the maintainers of WikiTI, for any reason, on IRC, please join #WikiTI on EFnet. If you do not have an IRC client, [http://chat.efnet.info/ use this]. You can find email addresses and IM names on each [[Special:Listadmins|administrator's]] User page (soon), or just leave a message on their Talk page.<br />
<br />
== Disclaimer ==<br />
WikiTI is not in any way affiliated with Texas Instruments Inc, or any of its subsidiaries, including the educational products division. No guarantee to accuracy is made of the information herein. Use at your own risk. [[Disclaimer|(Full Disclaimer)]]</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=83Plus:RAM:89F083Plus:RAM:89F02007-04-26T14:04:06Z<p>Dan Englender: Link to Flags by name category</p>
<hr />
<div>[[Category:83Plus:RAM:By Address|89F0 - Flags]][[Category:83Plus:RAM:By Name|Flags]]<br />
== Synopsis ==<br />
'''Official Name:''' Flags<br />
<br />
'''Memory Address:''' 89F0h<br />
<br />
'''Length:''' 60 bytes?<br />
<br />
<br />
This is the area where IY points to by default, all TI OS flags are located here.<br />
<br />
== Comments ==<br />
Could be longer than 60 bytes, location could be different on other models (89F0 for TI 83Plus)<br />
<br />
== See Also ==<br />
List of [[:Category:83Plus:Flags:By_Name|documented flags]].</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=83Plus:RAM:96F483Plus:RAM:96F42007-04-26T03:35:11Z<p>Dan Englender: Categories</p>
<hr />
<div>[[Category:83Plus:RAM:By Address|96F4 - editTop]][[Category:83Plus:RAM:By Name|editTop]]<br />
== Synopsis ==<br />
'''Official Name:''' editTop<br />
<br />
'''Memory Address:''' 96F4h<br />
<br />
'''Length:''' 2 bytes.<br />
<br />
<br />
This 2 byte address appears to be the minimum value of [[83Plus:RAM:96F6|editCursor]] in the current edit buffer.<br />
<br />
<br />
== Comments ==<br />
Could be useful in resetting buffers</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=83Plus:RAM:845A83Plus:RAM:845A2007-04-26T03:34:34Z<p>Dan Englender: lFont_record</p>
<hr />
<div>[[Category:83Plus:RAM:By_Address|845A - lFont_record]][[Category:83Plus:RAM:By Name|lFont_record]]<br />
== Synopsis ==<br />
'''Official Name:''' lFont_record<br />
<br />
'''Memory Address:''' 845A<br />
<br />
'''Length:''' 7 bytes.<br />
<br />
These seven bytes contain a bitmap of the space of the cursor - it can be the cursor itself or whatever is under the cursor. Only the rightmost 6 bits are used, 1 byte per row. <br />
<br />
== Comments ==<br />
Writing to this area does not seem to have any visible effect, so you might use this to store temporary variables. Remember that, if you do so, they will be destroyed as soon as the cursor does anything.</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=83Plus:RAM:96F483Plus:RAM:96F42007-04-26T03:32:54Z<p>Dan Englender: editTop</p>
<hr />
<div>[[Category:83Plus:RAM:By Address|96F4 - Unknown]]<br />
== Synopsis ==<br />
'''Official Name:''' editTop<br />
<br />
'''Memory Address:''' 96F4h<br />
<br />
'''Length:''' 2 bytes.<br />
<br />
<br />
This 2 byte address appears to be the minimum value of [[83Plus:RAM:96F6|editCursor]] in the current edit buffer.<br />
<br />
<br />
== Comments ==<br />
Could be useful in resetting buffers</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=Talk:Z80_Routines:Math:RandomTalk:Z80 Routines:Math:Random2007-04-03T14:22:36Z<p>Dan Englender: force ToC</p>
<hr />
<div>"Why isn't the table of contents showing up?"<br />
: I think the table of contents only shows up if there are three or more header entries, but I'm not sure. --[[User:Dan Englender|Dan Englender]] 07:14, 3 April 2007 (PDT)<br />
: On further reflection, the ToC only shows up if you have four or more header entries. However, if you want a table of contents on a page with fewer header entries, you can put <nowiki>__FORCETOC__</nowiki> in the page code to force a table of contents to be shown. ---[[User:Dan Englender|Dan Englender]] 07:22, 3 April 2007 (PDT)</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=SandboxSandbox2007-04-03T14:16:05Z<p>Dan Englender: </p>
<hr />
<div>a+bi<br />
<br />
χ²cdf(<br />
<br />
χ²pdf(<br />
<br />
χ²-Text(<br />
<br />
â–ºDec<br />
<br />
â–ºDMS<br />
<br />
e<br />
<br />
e^(<br />
<br />
â–ºEff(<br />
<br />
Equâ–ºString(<br />
<br />
�<br />
<br />
yay sandbox<br />
<br />
==one==<br />
one<br />
<br />
==two==<br />
two<br />
<br />
==three==<br />
three</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=SandboxSandbox2007-04-03T14:15:49Z<p>Dan Englender: </p>
<hr />
<div>a+bi<br />
<br />
χ²cdf(<br />
<br />
χ²pdf(<br />
<br />
χ²-Text(<br />
<br />
â–ºDec<br />
<br />
â–ºDMS<br />
<br />
e<br />
<br />
e^(<br />
<br />
â–ºEff(<br />
<br />
Equâ–ºString(<br />
<br />
�<br />
<br />
yay sandbox<br />
<br />
==one==<br />
one<br />
<br />
==two==<br />
two</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=Talk:Z80_Routines:Math:RandomTalk:Z80 Routines:Math:Random2007-04-03T14:14:38Z<p>Dan Englender: ToC</p>
<hr />
<div>"Why isn't the table of contents showing up?"<br />
: I think the table of contents only shows up if there are three or more header entries, but I'm not sure. --[[User:Dan Englender|Dan Englender]] 07:14, 3 April 2007 (PDT)</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=83Plus:Software:usb8x/Sample_Code83Plus:Software:usb8x/Sample Code2007-03-21T04:16:46Z<p>Dan Englender: /* Mouse Demo */</p>
<hr />
<div>Example code using the usb8x assembly and BASIC interfaces<br />
== BASIC ==<br />
=== Mouse Demo ===<br />
This example uses the [[../BASIC_Interface/MouseInit|MouseInit]], [[../BASIC_Interface/MouseDo|MouseDo]], and [[../BASIC_Interface/KillUSB|KillUSB]] entry points to control a point on the screen with a USB mouse.<br />
<nowiki>OpenLib(USBDRV8X<br />
{2 ;MouseInit<br />
ExecLib<br />
If Ans(1 ;If MouseInit returns error,<br />
Return ; then quit<br />
-1452->Xmin<br />
1452->Xmax<br />
-960->Ymin<br />
960->Ymax<br />
0->X<br />
0->Y<br />
Repeat getKey<br />
{3 ;MouseDo<br />
ExecLib<br />
Ans->L1<br />
If L1(1 ;If MouseDo returns error,<br />
Goto 1 ; restart loop<br />
If 127<L1(3 ;If x direction is left,<br />
L1(3)-256->L1(3 ; change to negative #<br />
If 127<L1(4 ;If y direction is up,<br />
L1(4)-256->L1(4 ; change to negative #<br />
Pt-Off(X,Y<br />
X+L1(3->X<br />
Y-L1(4->Y<br />
Pt-On(X,Y<br />
Lbl 1<br />
End<br />
{1 ;KillUSB<br />
ExecLib</nowiki><br />
<br />
=== Keyboard demo ===<br />
==== Simple Example ====<br />
This program waits for you to press a key and then echos back which one. Unlike the ASM demo in USB Tools, this one handles all of 'em. <br />
<br />
The requirement of <span style="font-variant: small-caps; font-size: 65%;">L</span>KBDSC being used to index an index is leftover from the early stages of this and somebody should reorganize the string so this isn't needed. Or not. Just an idea.<br />
:<br />
:OpenLib(USBDRV8X<br />
:{10<br />
:ExecLib <br />
:{40,0,12,153,120,0,132}&rarr;<span style="font-variant: small-caps; font-size: 65%;">L</span>BLANK<br />
:<br />
:While 1<br />
:{40,0,12,153,120,0,132}<br />
:While prod(Ans=<span style="font-variant: small-caps; font-size: 65%;">L</span>BLANK)=1<br />
:If getKey&ne;0<br />
:Goto SP<br />
:{11<br />
:ExecLib <br />
:End<br />
:<br />
:Ans(3&rarr;A<br />
:<span style="font-variant: small-caps; font-size: 65%;">L</span>KBDSC(A)&rarr;B<br />
:Disp sub(Str2,<span style="font-variant: small-caps; font-size: 65%;">L</span>KBLOC(B),<span style="font-variant: small-caps; font-size: 65%;">L</span>KBLEN(B<br />
:<br />
:End<br />
:<br />
:Lbl SP<br />
:{1<br />
:ExecLib <br />
:<br />
:Stop<br />
//Change the first line to "Goto D" and run this program once to get all of this information updated.<br />
:Lbl D<br />
:{94,95,96,53,76,74,55,37,56,57,58,42,59,60,61,78,77,43,44,35,38,54,39,41,75,36,<br />
73,40,72,15,16,17,18,19,20,21,22,23,24,64,1,28,34,86,25,26,45,46,27,0,62,63,14,7<br />
9,80,81,0,2,3,4,5,6,7,8,9,10,11,12,13,29,0,30,47,48,49,65,66,67,90,88,89,82,0,31<br />
,32,33,71,93,83,84,85,68,69,70,50,51,52,91,92,0,87}&rarr;<span style="font-variant: small-caps; font-size: 65%;">L</span>KBDSC<br />
:{3,2,2,2,2,2,2,2,2,2,3,3,3,5,1,1,1,1,1,1,1,1,1,1,1,1,4,9,12,5,5,5,5,3,1,1,1,1,1<br />
,1,1,1,1,1,1,1,6,4,7,5,5,5,1,1,1,1,1,1,1,1,1,1,1,5,6,3,9,5,5,5,5,1,1,1,1,1,1,1,1<br />
,1,1,2,5,5,5,5,13,4,4,5,5,5,9,4,4,4}&rarr;<span style="font-variant: small-caps; font-size: 65%;">L</span>KBLEN<br />
:{1,4,6,8,10,12,14,16,18,20,22,25,28,31,36,37,38,39,40,41,42,43,44,45,46,47,48,5<br />
2,61,73,78,83,88,93,96,97,98,99,100,101,102,103,104,105,106,107,108,114,118,125,<br />
130,135,140,141,142,143,144,145,146,147,148,149,150,151,156,162,165,174,179,184,<br />
189,194,195,196,197,198,199,200,201,202,203,204,206,211,216,221,226,239,243,247,<br />
252,257,262,271,275,279}&rarr;<span style="font-variant: small-caps; font-size: 65%;">L</span>KBLOC<br />
:"ESCF1F2F3F4F5F6F7F8F9F10F11F12Tilde1234567890-=SlshBackspacePrint ScreenPauseN<br />
UM /NUM *NUM -TABQWERTYUIOP[]InsertHomePage UpNUM 7NUM 8NUM 9ASDFGHJKL:'EnterDel<br />
eteEndPage DownNUM 4NUM 5NUM 6NUM +ZXCVBNM,./UpNUM 1NUM 2NUM 3Space<Right Click><br />
LeftDownRightNUM 0NUM .NUM Enter<01><02><03>"&rarr;Str2<br />
<br />
==== More Useful Example ====<br />
This example lets you type a string in using your actual keyboard. It doesn't know how to scroll, so you won't be able to type more than 128 characters, but they're still there.<br />
//The following lines are really frickin' long and stretched screens, so I put hard-returns without &lt;br&gt; tags. You can figure out where there's not supposed to be a break.<br />
//The <sup>&minus;</sup> is supposed to be a quote, but there's no way to store a quote into a string from within a string.<br />
:"abcdefghijklmnopqrstuvwxyz1234567890-=[]',./ ABCDEFGHIJKLMNOPQ<br />
RSTUVWXYZ~!^*()+_{} :<sup>&minus;</sup>&lt;&gt;? "&rarr;Str2<br />
:{0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,28,<br />
29,30,31,32,33,34,35,36,37,0,0,0,0,48,38,39,41,42,40,0,43,44,27,45,46,47,0,0,0,0<br />
,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0<br />
,0}&rarr;<span style="font-variant: small-caps; font-size: 65%;">L</span>KBSCL<br />
:OpenLib(USBDRV8X<br />
:{10<br />
:ExecLib<br />
:{40,0,12,153,120,0,132}&rarr;<span style="font-variant: small-caps; font-size: 65%;">L</span>BLANK<br />
:"&pi;&rarr;Str1<br />
:While 1<br />
:{40,0,12,153,120,0,132}<br />
:While prod(Ans=<span style="font-variant: small-caps; font-size: 65%;">L</span>BLANK)=1<br />
:If getKey&ne;0<br />
:Goto SP<br />
:{11<br />
:ExecLib <br />
:End<br />
:Ans&rarr;<span style="font-variant: small-caps; font-size: 65%;">L</span>TEMP<br />
:<span style="font-variant: small-caps; font-size: 65%;">L</span>TEMP(3&rarr;A<br />
:If A=42 and length(Str1)>1<br />
:Then<br />
:sub(Str1,1,length(Str1)-1&rarr;Str1<br />
:ClrHome<br />
:Output(1,1,Str1<br />
:End<br />
:If A=40<br />
:Goto E<br />
:If <span style="font-variant: small-caps; font-size: 65%;">L</span>KBSCL(A)=0<br />
:End<br />
:<br />
:<br />
:<br />
:<span style="font-variant: small-caps; font-size: 65%;">L</span>TEMP(2&rarr;S<br />
:0&rarr;T<br />
:S+(S-128<u>&gt;</u>0)(<sup>&minus;</sup>128&rarr;S<br />
:S+(S-64<u>&gt;</u>0)(<sup>&minus;</sup>64&rarr;S<br />
:If S-32<u>&gt;</u>0<br />
:Then<br />
:1&rarr;T<br />
:S-32&rarr;S<br />
:End<br />
:S+(S-16<u>&gt;</u>0)(<sup>&minus;</sup>16&rarr;S<br />
:S+(S-8<u>&gt;</u>0)(<sup>&minus;</sup>8&rarr;S<br />
:S+(S-4<u>&gt;</u>0)(<sup>&minus;</sup>4&rarr;S<br />
:If S-2<u>&gt;</u>0<br />
:Then<br />
:1&rarr;T<br />
:S-2&rarr;S<br />
:End<br />
:Str1+sub(Str2,<span style="font-variant: small-caps; font-size: 65%;">L</span>KBSCL(A)+(T=1)48,1&rarr;Str1<br />
:If length(Str1)=2 and sub(Str1,1,1)="&pi;<br />
:sub(Str1,2,1&rarr;Str1<br />
:Output(1,1,Str1<br />
:End<br />
:Lbl E<br />
:Lbl SP<br />
:{1<br />
:ExecLib<br />
:DelVar <span style="font-variant: small-caps; font-size: 65%;">L</span>TEMP<br />
:DelVar <span style="font-variant: small-caps; font-size: 65%;">L</span>MODS<br />
<br />
== Assembly (TASM) ==<br />
Code for TASM-compatible assemblers. Though usb8x is designed for use with ZDS, a TASM-syntax include file is provided as well.. TASM itself is apparently incompatible with usb8x macros, but they have been tested to work correctly with [http://benryves.com/bin/brass/ Brass]. Use [http://usb8x.cvs.sourceforge.net/*checkout*/usb8x/usb8x/usb8xtsm.inc usb8xtsm.inc] instead of [http://usb8x.cvs.sourceforge.net/*checkout*/usb8x/usb8x/usb8x.inc usb8x.inc]. <br />
=== Mouse Demo ===<br />
This code uses [[../Asm_Interface/DriverInit|DriverInit]], [[../Asm_Interface/Mouse/MouseInit|MouseInit]], [[../Asm_Interface/Mouse/MouseGetKey|MouseGetKey]], [[../Asm_Interface/HostKill|HostKill]], and [[../Asm_Interface/DriverKill|DriverKill]]. It is a replica of the mouse demo code from usb8x, though it doesn't include routines unrelated to USB. In this case the address of the callback routine passed to U_CALL_INIT doesn't matter, because MouseInit redefines the callback to handle the mouse data.<br />
<br />
<br />
{| border="0" cellpadding="0" cellspacing="0" <br />
|-<br />
||<br />
||'''<center>Brass</center>'''<br />
||'''<center>ZDS</center>'''<br />
|-<br />
|| <br />
<nowiki><br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
MainLoop:<br />
<br />
<br />
<br />
<br />
<br />
<br />
gkloop: <br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
MouseDone:<br />
<br />
<br />
</nowiki><br />
|| <br />
<nowiki><br />
U_CALL_INIT(Stub)<br />
jp c,error<br />
ld hl,USBDriverBuf<br />
U_CALL(DriverInit)<br />
jp c,error<br />
ld hl,DBuf<br />
ld bc,256<br />
bcall(_MemClear)<br />
ld de,DBuf<br />
ld b,0<br />
U_CALL(MouseInit)<br />
jp c,error<br />
bcall(_GrBufClr)<br />
xor a<br />
ld (MouseBtn),a<br />
ld a,50*2<br />
ld (MouseX),a<br />
ld a,32*2<br />
ld (MouseY),a<br />
call DispCursor<br />
<br />
bcall(_GrBufCpy)<br />
bcall(_GetCSC)<br />
cp skClear<br />
jr z,MouseDone<br />
call DispCursor<br />
ld b,4<br />
<br />
push bc<br />
U_CALL(MouseGetKey)<br />
call MouseUpdateCursor<br />
pop bc<br />
djnz gkloop<br />
call DispCursor<br />
jr MainLoop<br />
<br />
<br />
U_CALL(HostKill)<br />
U_CALL(DriverKill)<br />
ret</nowiki><br />
||<br />
<br />
<nowiki><br />
U_CALL_INIT Stub<br />
jp c,error<br />
ld hl,USBDriverBuf<br />
U_CALL DriverInit<br />
jp c,error<br />
ld hl,DBuf<br />
ld bc,256<br />
B_CALL MemClear<br />
ld de,DBuf<br />
ld b,0<br />
U_CALL MouseInit<br />
jp c,error<br />
B_CALL GrBufClr<br />
xor a<br />
ld (MouseBtn),a<br />
ld a,50*2<br />
ld (MouseX),a<br />
ld a,32*2<br />
ld (MouseY),a<br />
call DispCursor<br />
<br />
B_CALL GrBufCpy<br />
B_CALL GetCSC<br />
cp skClear<br />
jr z,MouseDone<br />
call DispCursor<br />
ld b,4<br />
<br />
push bc<br />
U_CALL MouseGetKey<br />
call MouseUpdateCursor<br />
pop bc<br />
djnz gkloop<br />
call DispCursor<br />
jr MainLoop<br />
<br />
<br />
U_CALL HostKill<br />
U_CALL DriverKill<br />
ret</nowiki><br />
<br />
||<br />
<nowiki><br />
;Initialize U_CALL system<br />
<br />
<br />
;Initialize usb8x driver<br />
<br />
<br />
<br />
;Clear descriptor buffer<br />
<br />
;allow diagonal keys<br />
;Initialize mouse driver<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
;Display mouse cursor<br />
<br />
<br />
<br />
<br />
<br />
;Erase cursor<br />
;Buffer copy is slow, so <br />
; update cursor a few times <br />
<br />
;Get mouse info from usb8x<br />
;Update cursor position<br />
<br />
<br />
;Re-display cursor<br />
<br />
<br />
<br />
;Disconnect power from mouse<br />
;Kill driver<br />
</nowiki><br />
<br />
|}<br />
<br />
== Assembly (ZDS) ==<br />
Code for ZDS compatible assemblers. usb8x is designed to be used with a ZDS-compatible assembler.<br />
<br />
=== FindPipe ===<br />
This code segment, taken from the mass storage driver, illustrates the use of [[../Asm_Interface/FindPipe|FindPipe]] to get the address of an endpoint matching certain characteristics.<br />
<nowiki> ld b,pipeBulk<br />
ld c,pipeOut<br />
ld hl,DescBuf<br />
U_CALL FindPipe ;Find an outgoing bulk endpoint<br />
jr c,error<br />
ld a,b<br />
ld (OutPipe),a ;Store the endpoint address for later use<br />
<br />
ld b,pipeBulk<br />
ld c,pipeIn<br />
ld hl,DescBuf<br />
U_CALL FindPipe ;Find an incoming bulk endpoint<br />
jr c,error<br />
ld a,b<br />
ld (InPipe),a</nowiki><br />
<br />
=== Keyboard Detect ===<br />
This code illustrates the use of [[../Asm_Interface/AutoSetup|AutoSetup]] and [[../Asm_Interface/GetClass|GetClass]] to determine if the attached device is a keyboard.<br />
<nowiki> U_CALL_INIT KBDCallBack ;Initialize U_CALL and Callback RAM calls<br />
jr c,NoUSBDriver ;If it returns C, that means USB8X isn't loaded on calc<br />
ld hl,USBDriverBuf<br />
U_CALL DriverInit ;Initialize USB driver<br />
ld hl,DescBuf<br />
U_CALL AutoSetup ;Initialize and configure USB device<br />
jr c,USBError<br />
<br />
ld hl,DescBuf<br />
U_CALL GetClass ;Get the class information for the attached device<br />
jr c,USBError<br />
cp 3 ;Keyboard class = 3<br />
jr nz,NotKBD<br />
dec b ;subclass = 1<br />
jr nz,NotKBD<br />
dec c ;protocol = 1<br />
jr nz,NotKBD<br />
;Keyboard is attached. Code would continue here. <br />
;Typically at this point you would call ReqData to start reading data from the keyboard</nowiki></div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=83Plus:BCALLs:454383Plus:BCALLs:45432007-03-20T14:15:02Z<p>Dan Englender: </p>
<hr />
<div>[[Category:83Plus:BCALLs:By_Name:Display|ClrLCD]] [[Category:83Plus:BCALLs:By_Name|ClrLCD]] [[Category:83Plus:BCALLs:By_Address|4543 - ClrLCD]]<br />
== Synopsis ==<br />
'''Official Name:''' ClrLCD<br />
<br />
'''BCALL Address:''' 4543<br />
<br />
Clears the display, ignoring any split-screen settings.<br />
<br />
=== Inputs ===<br />
* None<br />
<br />
=== Outputs === <br />
* None<br />
<br />
=== Destroys ===<br />
* All<br />
<br />
== Example ==<br />
<nowiki>B_CALL _ClrLCD</nowiki><br />
<br />
== Comments ==<br />
Indiscernible differences from ClrLCDFull</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=User_talk:Nyquist562User talk:Nyquist5622007-03-20T14:13:57Z<p>Dan Englender: Naming convention</p>
<hr />
<div>Hi, thanks for adding to the wiki. I just wanted to let you know when you add a BCALL the page should be named after the address number not the equate name. We do this because the addresses are unambiguous, whereas some BCALLs (especially undocumented ones) have multiple names. Look at an existing BCALL to see the naming convention, or check out the page on [[Contributing]]. Thanks! --[[User:Dan Englender|Dan Englender]] 07:13, 20 March 2007 (PDT)</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=Talk:83Plus:BCALLs:4543Talk:83Plus:BCALLs:45432007-03-20T14:08:10Z<p>Dan Englender: Talk:ClrLCD moved to Talk:83Plus:BCALLs:4543</p>
<hr />
<div>"Clears the display, ignoring any split-screen settings." .... I was under the impression that the difference between ClrLCDFull and ClrLCD was that the latter in fact does not ignore split screen settings and only clears the non-graph part of the screen. --[[User:Dan Englender|Dan Englender]] 07:03, 20 March 2007 (PDT)</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=Talk:ClrLCDTalk:ClrLCD2007-03-20T14:08:10Z<p>Dan Englender: Talk:ClrLCD moved to Talk:83Plus:BCALLs:4543: BCALL names should be addresses not equates.</p>
<hr />
<div>#redirect [[Talk:83Plus:BCALLs:4543]]</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=83Plus:BCALLs:454383Plus:BCALLs:45432007-03-20T14:08:09Z<p>Dan Englender: ClrLCD moved to 83Plus:BCALLs:4543</p>
<hr />
<div>[[Category:83Plus:BCALLs:By_Name:Display|ClrLCD]] [[Category:83Plus:BCALLs:By_Name|ClrLCD]] [[Category:83Plus:BCALLs:By_Address|4543 - ClrLCD]]<br />
== Synopsis ==<br />
'''Official Name:''' ClrLCD<br />
<br />
'''BCALL Address:''' 4543<br />
<br />
Clears the display, ignoring any split-screen settings.<br />
<br />
=== Inputs ===<br />
* None<br />
<br />
=== Outputs ===<br />
* None<br />
<br />
=== Destroys ===<br />
* All<br />
<br />
== Example ==<br />
<nowiki>B_CALL _ClrLCD</nowiki><br />
<br />
== Comments ==<br />
Indiscernible differences from ClrLCDFull</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=ClrLCDClrLCD2007-03-20T14:08:09Z<p>Dan Englender: ClrLCD moved to 83Plus:BCALLs:4543: BCALL names should be addresses not equates.</p>
<hr />
<div>#redirect [[83Plus:BCALLs:4543]]</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=Talk:83Plus:BCALLs:4543Talk:83Plus:BCALLs:45432007-03-20T14:03:59Z<p>Dan Englender: split screen is the difference between this and ClrLCDFull?</p>
<hr />
<div>"Clears the display, ignoring any split-screen settings." .... I was under the impression that the difference between ClrLCDFull and ClrLCD was that the latter in fact does not ignore split screen settings and only clears the non-graph part of the screen. --[[User:Dan Englender|Dan Englender]] 07:03, 20 March 2007 (PDT)</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=Talk:83Plus:BCALLs:529CTalk:83Plus:BCALLs:529C2007-03-09T06:58:06Z<p>Dan Englender: </p>
<hr />
<div>What happens if 8634 is not 0? --[[User:Dan Englender|Dan Englender]] 22:57, 8 March 2007 (PST)</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=Talk:83Plus:BCALLs:529CTalk:83Plus:BCALLs:529C2007-03-09T06:57:53Z<p>Dan Englender: </p>
<hr />
<div>What happens if 8639 is not 0? --[[User:Dan Englender|Dan Englender]] 22:57, 8 March 2007 (PST)</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=83Plus:BCALLs:523683Plus:BCALLs:52362007-03-01T19:56:46Z<p>Dan Englender: /* Destroys */ savesscreen -> saveSScreen</p>
<hr />
<div>[[Category:83Plus:BCALLs:By Name|RectBorder]]<br />
[[Category:83Plus:BCALLs:By Name:Display|RectBorder]]<br />
[[Category:83Plus:BCALLs:By Address|5236 - RectBorder]]<br />
<br />
----<br />
<br />
== Synopsis ==<br />
'''Unofficial Name:''' RectBorder<br />
<br />
'''BCALL Address:''' 5236<br />
<br />
'''Minimum OS Version: 2.30'''<br />
<br />
Either draws, erases, or inverts a rectangular border on the screen.<br />
<br />
=== Inputs ===<br />
* B: type of drawing (0 to erase, 1 to draw, 2 to invert)<br />
* H: upper left corner pixel row<br />
* L: upper left corner pixel column<br />
* D: lower right corner pixel row<br />
* E: lower right corner pixel column<br />
* plotLoc,(iy+plotFlags) set to update display only, reset for both display and graph buffer<br />
<br />
=== Outputs ===<br />
* Rectangle is drawn<br />
<br />
=== Destroys ===<br />
* [[83Plus:RAM:86EC|saveSScreen]]<br />
<br />
=== Comments ===<br />
This is the exact same thing as BCALLing [[83Plus:BCALLs:4D7D|DrawRectBorder]] or [[83Plus:BCALLs:4D86|EraseRectBorder]], though I suppose this has the advantage of being able to inverting it.<br />
<br />
It was added in OS 2.30. Do not attempt to BCALL it on an earlier version.</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=83Plus:BCALLs:523683Plus:BCALLs:52362007-03-01T19:55:53Z<p>Dan Englender: /* Comments */ 2.30+ not 2.30 only, I assume</p>
<hr />
<div>[[Category:83Plus:BCALLs:By Name|RectBorder]]<br />
[[Category:83Plus:BCALLs:By Name:Display|RectBorder]]<br />
[[Category:83Plus:BCALLs:By Address|5236 - RectBorder]]<br />
<br />
----<br />
<br />
== Synopsis ==<br />
'''Unofficial Name:''' RectBorder<br />
<br />
'''BCALL Address:''' 5236<br />
<br />
'''Minimum OS Version: 2.30'''<br />
<br />
Either draws, erases, or inverts a rectangular border on the screen.<br />
<br />
=== Inputs ===<br />
* B: type of drawing (0 to erase, 1 to draw, 2 to invert)<br />
* H: upper left corner pixel row<br />
* L: upper left corner pixel column<br />
* D: lower right corner pixel row<br />
* E: lower right corner pixel column<br />
* plotLoc,(iy+plotFlags) set to update display only, reset for both display and graph buffer<br />
<br />
=== Outputs ===<br />
* Rectangle is drawn<br />
<br />
=== Destroys ===<br />
* [[83Plus:RAM:86EC|savesscreen]]<br />
<br />
=== Comments ===<br />
This is the exact same thing as BCALLing [[83Plus:BCALLs:4D7D|DrawRectBorder]] or [[83Plus:BCALLs:4D86|EraseRectBorder]], though I suppose this has the advantage of being able to inverting it.<br />
<br />
It was added in OS 2.30. Do not attempt to BCALL it on an earlier version.</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=Talk:83Plus:Software:usb8x/BASIC_Interface/KBDGetKeyTalk:83Plus:Software:usb8x/BASIC Interface/KBDGetKey2007-01-28T02:02:20Z<p>Dan Englender: What are getKey codes?</p>
<hr />
<div>"It'd be nice to get a normal BASIC getKey-style return code. Perhaps the KBD driver wrapper could overwrite H (element 6, which is usually zero anyway) with that before returing."<br />
: What key code format is used by BASIC getKey? If someone has code to convert GetKey codes to getKey codes, I'll put in usb8x no problem. --[[User:Dan Englender|Dan Englender]] 18:02, 27 January 2007 (PST)</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=User_talk:Dan_EnglenderUser talk:Dan Englender2007-01-11T04:51:18Z<p>Dan Englender: </p>
<hr />
<div>Hi, I'm Dan.<br />
<br />
== Page 0 Calls -> Maybe we could create a new section? ==<br />
<br />
Hi Dan,<br />
<br />
<br />
<br />
I made a page about page 0 calls. (like CALL 2EEE)<br />
<br />
Maybe you could create a new section for it?<br />
<br />
It seems to be a source of much functions.<br />
<br />
Thanks for your time.<br />
<br />
<br />
<br />
Sernin van de Krol<br />
<br />
---[[User:84plusfreak|84plusfreak]] 09:01, 7 Jun 2005 (PDT)<br />
: Discussion moved [[Talk:83Plus:OS:Page_0_Calls|here]] --[[User:Dan Englender|Dan Englender]] 15:15, 7 Jun 2005 (PDT)<br />
<br />
== USB Mouse ==<br />
<br />
Can I have that App? And the instructions for connecting the mouse? ---[[User:84plusfreak|84plusfreak]] 05:22, 28 Jun 2005 (PDT)<br />
<br />
:The app as currently written is not very useful for anything other than a mouse demo or reading standard descriptors. Source will be up soon though, once I clean it up and start working on a driver layer. As for connecting the mouse, you just need to get some sort of adaptor or cable with a mini-A plug on one end, and a standard A female on the other end. I'm using the Gold-X Quick Connect 5 in 1 set, but I think there are other options on the market too. --[[User:Dan Englender|Dan Englender]] 13:49, 28 Jun 2005 (PDT)<br />
<br />
:: Wal*mart has a universal cable for $15. --[[User:AndyJ|AndyJ]] 14:54, 28 Jun 2005 (PDT)<br />
<br />
::: I live in The Netherlands, so the Wal*mart is a little bit too far away. ;-) --[[User:84plusfreak|84plusfreak]] 06:20, 2 Nov 2005 (PST)<br />
<br />
To whoever felt to need to add my last name to my user page: *shrug*<br />
:yeah... User pages should only be edited by the user to whom it belongs.... [[User:AndyJ|Andy Janata]] 18:02, 31 Oct 2005 (PST)<br />
<br />
== 84 Plus and 84 Plus Silver Edition ==<br />
How come there is no designated page for these two? I see that there is some information on it though. This should be fixed.<br />
<br />
== Press-to-Test == <br />
how can I request information on this? {{unsigned|Misterdan|16:15, 10 January 2007 }}<br />
<br />
== TestGuard 2.0 ==<br />
information on this should also be supplied {{unsigned|Misterdan|16:19, 10 January 2007}}<br />
: Well if you create a page for the topics and put a missing info or stub templates that'll at least get it on the appropriate pages. But people mainly add information about what they're interested in researching, so if you can find someone interested in researching press-to-test or testguard you're more likely to get some information. --[[User:Dan Englender|Dan Englender]] 20:51, 10 January 2007 (PST)</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=User_talk:Dan_EnglenderUser talk:Dan Englender2007-01-11T04:47:37Z<p>Dan Englender: signing unsigned</p>
<hr />
<div>Hi, I'm Dan.<br />
<br />
== Page 0 Calls -> Maybe we could create a new section? ==<br />
<br />
Hi Dan,<br />
<br />
<br />
<br />
I made a page about page 0 calls. (like CALL 2EEE)<br />
<br />
Maybe you could create a new section for it?<br />
<br />
It seems to be a source of much functions.<br />
<br />
Thanks for your time.<br />
<br />
<br />
<br />
Sernin van de Krol<br />
<br />
---[[User:84plusfreak|84plusfreak]] 09:01, 7 Jun 2005 (PDT)<br />
: Discussion moved [[Talk:83Plus:OS:Page_0_Calls|here]] --[[User:Dan Englender|Dan Englender]] 15:15, 7 Jun 2005 (PDT)<br />
<br />
== USB Mouse ==<br />
<br />
Can I have that App? And the instructions for connecting the mouse? ---[[User:84plusfreak|84plusfreak]] 05:22, 28 Jun 2005 (PDT)<br />
<br />
:The app as currently written is not very useful for anything other than a mouse demo or reading standard descriptors. Source will be up soon though, once I clean it up and start working on a driver layer. As for connecting the mouse, you just need to get some sort of adaptor or cable with a mini-A plug on one end, and a standard A female on the other end. I'm using the Gold-X Quick Connect 5 in 1 set, but I think there are other options on the market too. --[[User:Dan Englender|Dan Englender]] 13:49, 28 Jun 2005 (PDT)<br />
<br />
:: Wal*mart has a universal cable for $15. --[[User:AndyJ|AndyJ]] 14:54, 28 Jun 2005 (PDT)<br />
<br />
::: I live in The Netherlands, so the Wal*mart is a little bit too far away. ;-) --[[User:84plusfreak|84plusfreak]] 06:20, 2 Nov 2005 (PST)<br />
<br />
To whoever felt to need to add my last name to my user page: *shrug*<br />
:yeah... User pages should only be edited by the user to whom it belongs.... [[User:AndyJ|Andy Janata]] 18:02, 31 Oct 2005 (PST)<br />
<br />
== 84 Plus and 84 Plus Silver Edition ==<br />
How come there is no designated page for these two? I see that there is some information on it though. This should be fixed.<br />
<br />
== Press-to-Test == <br />
how can I request information on this? {{unsigned|Misterdan|16:15, 10 January 2007 }}<br />
<br />
== TestGuard 2.0 ==<br />
information on this should also be supplied {{unsigned|Misterdan|16:19, 10 January 2007}}</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=83Plus:Software:usb8x/Asm_Interface/Pump83Plus:Software:usb8x/Asm Interface/Pump2007-01-08T19:15:56Z<p>Dan Englender: /* Notes */ typo</p>
<hr />
<div>== Synopsis ==<br />
'''Name:''' Pump<br />
<br />
'''Minimum usb8x version:''' 0.12<br />
<br />
Polls the USB port for activity and handles it appropriately. Use this routine when the pump system has been enabled with [[../PumpOn|PumpOn]]. When the pump system is enabled, USB interrupts will be disabled, which means no USB data will be recieved unless the Pump routine is called periodically. The pump system should be used if you want to access the USB port with the TIOS interrupt, or all interrupts, disabled.<br />
<br />
=== Inputs ===<br />
''None''<br />
<br />
=== Outputs ===<br />
''None''<br />
<br />
=== Destroys ===<br />
''None''<br />
<br />
== Notes ==<br />
Make sure to call [[../PumpOn|PumpOn]] before using this routine. Be sure to call [[../PumpOff|PumpOff]] when you're done so that USB interrupts will be re-enabled. Pump may call your callback routine if data is recieved on the USB port. If you are using the MSD driver, you do not need to call Pump when using the pump system. The MSD routines will call it internally.<br />
<br />
== See Also ==<br />
* [[../PumpOn|PumpOn]] - Turn on the pump system<br />
* [[../PumpOff|PumpOff]] - Turn off the pump system</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=83Plus:BCALLs:4F5483Plus:BCALLs:4F542006-12-26T05:20:06Z<p>Dan Englender: /* Notes */</p>
<hr />
<div>[[Category:83Plus:BCALLs:By Name|GetBytePaged]] [[Category:83Plus:BCALLs:By Address|4F54 - GetBytePaged]]<br />
== Synopsis ==<br />
'''Unofficial Name:''' GetBytePaged<br />
<br />
'''BCALL Address:''' 4F54<br />
<br />
Gets a byte from a specific page and address.<br />
<br />
=== Inputs ===<br />
* HL = offset into page where byte is located (4000h-7FFFh).<br />
* A = page where byte is located.<br />
<br />
=== Outputs ===<br />
* B = byte.<br />
<br />
=== Destroys ===<br />
* A, C<br />
<br />
== Notes ==<br />
Registers A and C are destroyed to restore the page located in [[83Plus:Ports:06|bank A]] after this call completes.<br />
<br />
In theory, it works for any ROM or RAM page, but will fail if passed A=0. The OS uses it to quickly read a byte from Flash ROM.<br />
<br />
== Example ==<br />
Get first byte of page 03h:<br />
<br />
ld a,03h<br />
ld hl,4000h<br />
B_CALL GetBytePaged<br />
;B contains byte</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=Talk:83Plus:BCALLs:4F54Talk:83Plus:BCALLs:4F542006-12-26T05:17:06Z<p>Dan Englender: </p>
<hr />
<div>== Why not ROM page 0? ==<br />
<br />
The very first opcodes of this bcall are <tt>or a \ ret z</tt>. Unless my memory fails miserably, this means it won't work on ROM page 0. -[[User:AndyJ|Andy Janata]] 10:32, 24 December 2006 (PST)<br />
: Yeah, you're right, but ROM page 0 is always loaded at 0000h, so you could pass a non-zero value in A and point HL to ROM page 0. (It would be pointless, but you could do it.) Thanks for pointing that out. I'll update the article accordingly. --[[User:Dan Englender|Dan Englender]] 21:17, 25 December 2006 (PST)</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=83Plus:BCALLs:4F5483Plus:BCALLs:4F542006-12-20T16:10:40Z<p>Dan Englender: /* Notes */ Why not 0?</p>
<hr />
<div>[[Category:83Plus:BCALLs:By Name|GetBytePaged]] [[Category:83Plus:BCALLs:By Address|4F54 - GetBytePaged]]<br />
== Synopsis ==<br />
'''Unofficial Name:''' GetBytePaged<br />
<br />
'''BCALL Address:''' 4F54<br />
<br />
Gets a byte from a specific page and address.<br />
<br />
=== Inputs ===<br />
* HL = offset into page where byte is located (4000h-7FFFh).<br />
* A = page where byte is located.<br />
<br />
=== Outputs ===<br />
* B = byte.<br />
<br />
=== Destroys ===<br />
* A, C<br />
<br />
== Notes ==<br />
Registers A and C are destroyed to restore the page located in [[83Plus:Ports:06|bank A]] after this call completes.<br />
<br />
In theory, it works for any ROM or RAM page, but the OS uses it to quickly read a byte from Flash ROM.<br />
<br />
== Example ==<br />
Get first byte of page 03h:<br />
<br />
ld a,03h<br />
ld hl,4000h<br />
B_CALL GetBytePaged<br />
;B contains byte</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=83Plus:Software:usb8x/Supported_Devices83Plus:Software:usb8x/Supported Devices2006-11-28T20:21:38Z<p>Dan Englender: /* Internal Driver */ Dazzle Zio All in 1 Reader</p>
<hr />
<div>Most USB devices that are self-powered, or draw 100mA or less current from the USB bus should be compatible with usb8x. Below is a list of device classes and specific devices that have been tested. Devices that require isochronous endpoints or have an integrated USB hub are not currently compatible.<br />
<br />
== Internal Driver ==<br />
These devices work and usb8x contains an internal driver to control them.<br />
* HID Keyboard<br />
* HID Mouse<br />
* Mass Storage Device. Tested with:<br />
** Sandisk Cruzer<br />
** Lexar JumpDrive/Secure<br />
** SMI Corp USB Disk<br />
** 512 Mini Disk Genie<br />
** PQI Intelligent Stick<br />
** Dazzle Zio All in 1 Reader (required external power supply).<br />
* TI Silverlink<br />
* Some gamepad controllers. Tested with:<br />
** Logitech Precision Gamepad<br />
** Logitech Dual Action Gamepad (only the buttons, the D-pad and joysticks don't work)<br />
** [http://www.retrousb.com/nintendo.html RetroZone NES pad]<br />
** [http://www.planetgamecube.com/hardArt.cfm?artid=2459 Skillz Gamecube to USB] (The company no longer seems to exist.)<br />
* Vernier EasyTemp<br />
<br />
== External Driver ==<br />
These devices work and an external driver exists to control them.<br />
* None<br />
<br />
== Works, No Complete Driver ==<br />
These devices have been tested to work with usb8x, but no complete driver currently exists.<br />
* EMS HID Playstation 2 controller adapter<br />
* HID Mouse/Keyboard Combo (I ([[User:84plusfreak|84plusfreak]]) am writing a driver for it.)<br />
<br />
== Should Work ==<br />
These devices have been tested to properly initialize with usb8x, but no drivers have been attempted.<br />
* Canon i850 printer<br />
* Canon SD400 digital camera<br />
* Motorola SURFboard cable modem<br />
* Motorola V220 (can act as USB Modem)<br />
* TI-84 Plus (calc<->calc)<br />
* Generic IrDA USB dongle (says it draws 440 mA, but it initializes fine anyway)<br />
<br />
== Not Compatible ==<br />
These devices are not compatible with usb8x.<br />
* Ezonics webcam - isochronous endpoints<br />
* Netgear WG111 802.11 adapter - draws too much current?<br />
* SMC 802.11b adapter - draws too much current<br />
* Taurus MBT-1203 bluetooth adapter - has integrated hub</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=Talk:Z80_Instruction_SetTalk:Z80 Instruction Set2006-11-28T14:43:09Z<p>Dan Englender: </p>
<hr />
<div>We could probably just use one of the publically available instruction set lists to save the time and trouble of typing everything out again.<br />
--Dan 00:28, 22 Dec 2005<br />
<br />
:Emacs.<br />
:Anyway, what you've got so far is not particularly clear, and doesn't really present the important information. I'm thinking of a series of tables something like this:<br />
<br />
{| border="1" cellpadding="2"<br />
! Oct !! Hex !! Instruction !! States !! Clock !! S !! Z !! X !! H !! Y !! P !! N !! C<br />
|-<br />
| 100 || 40 || ld b, b || OCF(4) || 4 || - || - || - || - || - || - || - || -<br />
|-<br />
| 101 || 41 || ld b, c || OCF(4) || 4 || - || - || - || - || - || - || - || -<br />
|-<br />
| 102 || 42 || ld b, d || OCF(4) || 4 || - || - || - || - || - || - || - || -<br />
|-<br />
| 103 || 43 || ld b, e || OCF(4) || 4 || - || - || - || - || - || - || - || -<br />
|}<br />
<br />
:A quick reference for people who actually know what they're doing. For those who don't, these tables should of course be accompanied by detailed descriptions of what the various opcodes actually do.<br />
:Any comments before I go and waste a few hours wikifying the rest of the Z80 instruction set?<br />
::Perhaps we can be more intelligent about this and not do this by hand? At least have some source file and then we have a nice program we auto-generate the list from? I sure don't want you wasting hours wikifying the instruction set, no matter how good vi might be. ;-) --[[User:JasonM|JasonM]] 14:13, 30 Dec 2005 (PST)<br />
:Please don't use parentheses for anything other than indirection!<br />
:[[User:FloppusMaximus|FloppusMaximus]] 12:28, 23 Dec 2005 (PST)<br />
::Is providing an octal representation actually useful for anything?<br />
<br />
:A binary representation would be more useful -- [[User:Jib|Jib]]<br />
<br />
::You're right, it could be. Of course octal is useful -- just take a look at a complete table of the instructions; everything is grouped by eights and sixty-fours. So I know that 1''r'' ''s'' = LD ''r'',''s'', or that 3''a''6 ''nnn'' = ALU(''a'') ''nnn'', or that 3''z''7 = RST 0''z''0, or less obviously that 3''c''0 = RET ''c''. Much easier to remember than hexadecimal. But that's just me. I think you're right, binary would be better. [[User:FloppusMaximus|FloppusMaximus]] 15:53, 25 Dec 2005 (PST)<br />
:::Can we just do both? I think I have enough screen real-estate. --[[User:JasonM|JasonM]] 14:13, 30 Dec 2005 (PST)<br />
<br />
:Since I coded the Z80 core of PindurTI from scratch, I have some useful information at my disposal that I hunted down from various places on the web, especially regarding flags. A big table would be the most effective method in my opinion, I'll start building something on my user page. [[User:CoBB|CoBB]] 02:52, 25 Feb 2006 (PST)<br />
<br />
Considering the length of the table, would it be a good idea to repeat the column headers every so often (so people don't have to scroll all the way back up to see what order the flags are in, for example - easy to get lost with such narrow columns)? -- [[User:Aquanight|Aquanight]] 20:49, 27 November 2006 (PST)<br />
: Yes --[[User:Dan Englender|Dan Englender]] 06:43, 28 November 2006 (PST)</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=83Plus:Software:usb8x/Sample_Code83Plus:Software:usb8x/Sample Code2006-11-17T06:14:47Z<p>Dan Englender: /* Keyboard Detect */ typo</p>
<hr />
<div>Example code using the usb8x assembly and BASIC interfaces<br />
== BASIC ==<br />
=== Mouse Demo ===<br />
This example uses the [[../BASIC_Interface/MouseInit|MouseInit]], [[../BASIC_Interface/MouseDo|MouseDo]], and [[../BASIC_Interface/KillUSB|KillUSB]] entry points to control a point on the screen with a USB mouse.<br />
<nowiki>OpenLib(USBDRV8X<br />
{2 ;MouseInit<br />
ExecLib<br />
If Ans(1 ;If MouseInit returns error,<br />
Return ; then quit<br />
-1452->Xmin<br />
1452->Xmax<br />
-960->Ymin<br />
960->Ymax<br />
0->X<br />
0->Y<br />
Repeat getKey<br />
{3 ;MouseDo<br />
ExecLib<br />
Ans->L1<br />
If L1(1 ;If MouseDo returns error,<br />
Goto 1 ; restart loop<br />
If 127<L1(3 ;If x direction is left,<br />
L1(3)-256->L1(3 ; change to negative #<br />
If 127<L1(4 ;If y direction is up,<br />
L1(4)-256->L1(4 ; change to negative #<br />
Pt-Off(X,Y<br />
X+L1(3->X<br />
Y-L1(4->Y<br />
Pt-On(X,Y<br />
Lbl 1<br />
End<br />
{1 ;KillUSB<br />
ExecLib</nowiki><br />
<br />
== Assembly (TASM) ==<br />
Code for TASM-compatible assemblers. Though usb8x is designed for use with ZDS, a TASM-syntax include file is provided as well.. TASM itself is apparently incompatible with usb8x macros, but they have been tested to work correctly with [http://benryves.com/bin/brass/ Brass]. Use [http://usb8x.cvs.sourceforge.net/*checkout*/usb8x/usb8x/usb8xtsm.inc usb8xtsm.inc] instead of [http://usb8x.cvs.sourceforge.net/*checkout*/usb8x/usb8x/usb8x.inc usb8x.inc]. <br />
=== Mouse Demo ===<br />
This code uses [[../Asm_Interface/DriverInit|DriverInit]], [[../Asm_Interface/Mouse/MouseInit|MouseInit]], [[../Asm_Interface/Mouse/MouseGetKey|MouseGetKey]], [[../Asm_Interface/HostKill|HostKill]], and [[../Asm_Interface/DriverKill|DriverKill]]. It is a replica of the mouse demo code from usb8x, though it doesn't include routines unrelated to USB. In this case the address of the callback routine passed to U_CALL_INIT doesn't matter, because MouseInit redefines the callback to handle the mouse data.<br />
<br />
<br />
{| border="0" cellpadding="0" cellspacing="0" <br />
|-<br />
||<br />
||'''<center>Brass</center>'''<br />
||'''<center>ZDS</center>'''<br />
|-<br />
|| <br />
<nowiki><br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
MainLoop:<br />
<br />
<br />
<br />
<br />
<br />
<br />
gkloop: <br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
MouseDone:<br />
<br />
<br />
</nowiki><br />
|| <br />
<nowiki><br />
U_CALL_INIT(Stub)<br />
jp c,error<br />
ld hl,USBDriverBuf<br />
U_CALL(DriverInit)<br />
jp c,error<br />
ld hl,DBuf<br />
ld bc,256<br />
bcall(_MemClear)<br />
ld de,DBuf<br />
ld b,0<br />
U_CALL(MouseInit)<br />
jp c,error<br />
bcall(_GrBufClr)<br />
xor a<br />
ld (MouseBtn),a<br />
ld a,50*2<br />
ld (MouseX),a<br />
ld a,32*2<br />
ld (MouseY),a<br />
call DispCursor<br />
<br />
bcall(_GrBufCpy)<br />
bcall(_GetCSC)<br />
cp skClear<br />
jr z,MouseDone<br />
call DispCursor<br />
ld b,4<br />
<br />
push bc<br />
U_CALL(MouseGetKey)<br />
call MouseUpdateCursor<br />
pop bc<br />
djnz gkloop<br />
call DispCursor<br />
jr MainLoop<br />
<br />
<br />
U_CALL(HostKill)<br />
U_CALL(DriverKill)<br />
ret</nowiki><br />
||<br />
<br />
<nowiki><br />
U_CALL_INIT Stub<br />
jp c,error<br />
ld hl,USBDriverBuf<br />
U_CALL DriverInit<br />
jp c,error<br />
ld hl,DBuf<br />
ld bc,256<br />
B_CALL MemClear<br />
ld de,DBuf<br />
ld b,0<br />
U_CALL MouseInit<br />
jp c,error<br />
B_CALL GrBufClr<br />
xor a<br />
ld (MouseBtn),a<br />
ld a,50*2<br />
ld (MouseX),a<br />
ld a,32*2<br />
ld (MouseY),a<br />
call DispCursor<br />
<br />
B_CALL GrBufCpy<br />
B_CALL GetCSC<br />
cp skClear<br />
jr z,MouseDone<br />
call DispCursor<br />
ld b,4<br />
<br />
push bc<br />
U_CALL MouseGetKey<br />
call MouseUpdateCursor<br />
pop bc<br />
djnz gkloop<br />
call DispCursor<br />
jr MainLoop<br />
<br />
<br />
U_CALL HostKill<br />
U_CALL DriverKill<br />
ret</nowiki><br />
<br />
||<br />
<nowiki><br />
;Initialize U_CALL system<br />
<br />
<br />
;Initialize Driver<br />
<br />
<br />
<br />
;Clear descriptor buffer<br />
<br />
;allow diagonal keys<br />
;Initialize Mouse<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
;Display mouse cursor<br />
<br />
<br />
<br />
<br />
<br />
;Erase cursor<br />
;Buffer copy is slow, so <br />
; update cursor a few times <br />
<br />
;Get mouse info from usb8x<br />
;Update cursor position<br />
<br />
<br />
;Re-display cursor<br />
<br />
<br />
<br />
;Disconnect power from mouse<br />
;Kill driver<br />
</nowiki><br />
<br />
|}<br />
<br />
== Assembly (ZDS) ==<br />
Code for ZDS compatible assemblers. usb8x is designed to be used with a ZDS-compatible assembler.<br />
<br />
=== FindPipe ===<br />
This code segment, taken from the mass storage driver, illustrates the use of [[../Asm_Interface/FindPipe|FindPipe]] to get the address of an endpoint matching certain characteristics.<br />
<nowiki> ld b,pipeBulk<br />
ld c,pipeOut<br />
ld hl,DescBuf<br />
U_CALL FindPipe ;Find an outgoing bulk endpoint<br />
jr c,error<br />
ld a,b<br />
ld (OutPipe),a ;Store the endpoint address for later use<br />
<br />
ld b,pipeBulk<br />
ld c,pipeIn<br />
ld hl,DescBuf<br />
U_CALL FindPipe ;Find an incoming bulk endpoint<br />
jr c,error<br />
ld a,b<br />
ld (InPipe),a</nowiki><br />
<br />
=== Keyboard Detect ===<br />
This code illustrates the use of [[../Asm_Interface/AutoSetup|AutoSetup]] and [[../Asm_Interface/GetClass|GetClass]] to determine if the attached device is a keyboard.<br />
<nowiki> U_CALL_INIT KBDCallBack ;Initialize U_CALL and Callback RAM calls<br />
jr c,NoUSBDriver ;If it returns C, that means USB8X isn't loaded on calc<br />
ld hl,USBDriverBuf<br />
U_CALL DriverInit ;Initialize USB driver<br />
ld hl,DescBuf<br />
U_CALL AutoSetup ;Initialize and configure USB device<br />
jr c,USBError<br />
<br />
ld hl,DescBuf<br />
U_CALL GetClass ;Get the class information for the attached device<br />
jr c,USBError<br />
cp 3 ;Keyboard class = 3<br />
jr nz,NotKBD<br />
dec b ;subclass = 1<br />
jr nz,NotKBD<br />
dec c ;protocol = 1<br />
jr nz,NotKBD<br />
;Keyboard is attached. Code would continue here. <br />
;Typically at this point you would call ReqData to start reading data from the keyboard</nowiki></div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=83Plus:BCALLs:450483Plus:BCALLs:45042006-11-07T16:59:33Z<p>Dan Englender: "update" -> "advance"</p>
<hr />
<div>== Synopsis ==<br />
'''Official Name:''' PutC<br />
<br />
'''BCALL Address:''' 4504<br />
<br />
Displays a character on screen in the large font at the current cursor location and advances the cursor position.<br />
<br />
=== Inputs ===<br />
* A = TI-ASCII code of character to display<br />
<br />
=== Outputs ===<br />
* character at coordinate ([[83Plus:RAM:844B|curRow]], [[83Plus:RAM:844C|curCol]])<br />
<br />
=== Destroys ===<br />
* none<br />
<br />
== Comments ==<br />
This B_CALL is the same as [[83Plus:BCALLs:4501|PutMap]], except that it advances the cursor.<br />
<br />
[[Category:83Plus:BCALLs:By Name|PutC]]<br />
[[Category:83Plus:BCALLs:By Name:Text|PutC]]<br />
[[Category:83Plus:BCALLs:By Address|4504 - PutC]]</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=83Plus:BCALLs:450183Plus:BCALLs:45012006-11-07T16:58:32Z<p>Dan Englender: /* Comments */ minor reword and link to PutC</p>
<hr />
<div>== Synopsis ==<br />
'''Official Name:''' PutMap<br />
<br />
'''BCALL Address:''' 4501<br />
<br />
Displays a character on screen in the large font at the current cursor location.<br />
<br />
=== Inputs ===<br />
* A = TI-ASCII code of character to display<br />
<br />
=== Outputs ===<br />
* character at coordinate ([[83Plus:RAM:844B|curRow]], [[83Plus:RAM:844C|curCol]])<br />
<br />
=== Destroys ===<br />
* none<br />
<br />
== Comments ==<br />
This B_CALL displays, in large font, the character stored in A at the current cursor location without advancing the cursor. The [[83Plus:BCALLs:4504|PutC]] entry point is similar except it advances the cursor.<br />
<br />
== Example ==<br />
Shows &Eacute; in the upper-left hand corner of the screen:<br />
<nowiki>ld a, LcapEAcute<br />
ld hl, $0000<br />
ld (curRow),hl<br />
B_CALL PutMap</nowiki><br />
<br />
[[Category:83Plus:BCALLs:By Name|PutMap]]<br />
[[Category:83Plus:BCALLs:By Name:Text|PutMap]]<br />
[[Category:83Plus:BCALLs:By Address|4501 - PutMap]]</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=Talk:Calculator_DocumentationTalk:Calculator Documentation2006-11-05T17:11:30Z<p>Dan Englender: Forgot to sign</p>
<hr />
<div>I changed some headings and moved stuff around a bit. I think it's more logical this way, but I don't mind if you change it back. [[User:Jib|Jib]] 02:37, 5 November 2006 (PST)<br />
: The only thing that bugs me about it is that there's a "software" heading that includes both PC software (emulators) and calculator software (TIOS Alternatives), not to mention that software documentation is listed under a different heading. What do you think about:<br />
Z80 Calculators<br />
TI-83<br />
Programming<br />
Ports<br />
RAM Areas<br />
B_CALLs<br />
etc<br />
Software<br />
Calculator Software<br />
Emulators<br />
Linking Software<br />
TIOS Alternatives<br />
TI-83 Plus Family<br />
Programming<br />
etc...<br />
Software<br />
etc...<br />
General Z80 Info<br />
Instruction Set<br />
etc.<br />
<br />
68k Calculators<br />
TI-89/92+<br />
Programming<br />
etc.<br />
Software<br />
etc.<br />
TI-92<br />
etc.<br />
General 68k Info<br />
Instruction Set<br />
etc.<br />
<br />
TI Community<br />
History<br />
Programming Teams<br />
etc.<br />
<br />
For example, in that organization, the TI-83 Emulators page would basically just be a list of the emulators compatible with the 83, each of which would have their own separate page. So the VTI page might be linked from the TI-83 emulators page, the TI-85 emulators page, the TI-89 emulators page, etc. I like this organization because it makes it clear what calculators everything is applicable to, and it decreases the number of top-level categories. But maybe it's too complicated or has too many levels. Thoughts? --[[User:Dan Englender|Dan Englender]] 09:11, 5 November 2006 (PST)</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=Talk:Calculator_DocumentationTalk:Calculator Documentation2006-11-05T17:10:33Z<p>Dan Englender: </p>
<hr />
<div>I changed some headings and moved stuff around a bit. I think it's more logical this way, but I don't mind if you change it back. [[User:Jib|Jib]] 02:37, 5 November 2006 (PST)<br />
: The only thing that bugs me about it is that there's a "software" heading that includes both PC software (emulators) and calculator software (TIOS Alternatives), not to mention that software documentation is listed under a different heading. What do you think about:<br />
Z80 Calculators<br />
TI-83<br />
Programming<br />
Ports<br />
RAM Areas<br />
B_CALLs<br />
etc<br />
Software<br />
Calculator Software<br />
Emulators<br />
Linking Software<br />
TIOS Alternatives<br />
TI-83 Plus Family<br />
Programming<br />
etc...<br />
Software<br />
etc...<br />
General Z80 Info<br />
Instruction Set<br />
etc.<br />
<br />
68k Calculators<br />
TI-89/92+<br />
Programming<br />
etc.<br />
Software<br />
etc.<br />
TI-92<br />
etc.<br />
General 68k Info<br />
Instruction Set<br />
etc.<br />
<br />
TI Community<br />
History<br />
Programming Teams<br />
etc.<br />
<br />
For example, in that organization, the TI-83 Emulators page would basically just be a list of the emulators compatible with the 83, each of which would have their own separate page. So the VTI page might be linked from the TI-83 emulators page, the TI-85 emulators page, the TI-89 emulators page, etc. I like this organization because it makes it clear what calculators everything is applicable to, and it decreases the number of top-level categories. But maybe it's too complicated or has too many levels. Thoughts?</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=83Plus:OS:84_Plus_USB_Information83Plus:OS:84 Plus USB Information2006-11-01T17:11:08Z<p>Dan Englender: /* Hardware */ port 89 w/minor to port87</p>
<hr />
<div>:I moved this page from Talk:83Plus:BCALLs:5254 to here because it seems to fit better. Please note that this is still a work in progress, and don't take the information as gold. I figured having an option for a Talk page for this would outweigh the moving of it. For the time being, we'll leave the data formatted as-is, since it's still nicely done. --[[User:AndyJ|AndyJ]] 07:44, 27 May 2005 (PDT)<br />
<br />
<br />
<br />
OK, I've started this talk page to post information about the 84 Plus USB. This isn't the ideal place, since not all of this stuff has to do with entry point 5254, but it'll have to do. If anyone else would like to contribute any information or thoughts, please do so. Much of this data has been discovered by analyzing how the EasyData application interacts with the EasyTemp probe. --[[User:Dan Englender|Dan Englender]] 22:32, 23 May 2005 (PDT)<br />
<br />
Many thanks to Olivier Armand for providing information invaluable to figuring out some of the harder to decipher USB ports. --[[User:Dan Englender|Dan Englender]] 23:25, 9 Jul 2005 (PDT)<br />
<br />
== Easy Data ==<br />
The USB entry points that Easy Data uses are:<br />
5254<br />
5257<br />
525A<br />
525D<br />
5260<br />
<br />
These routines return carry flag with an error code in A on failure, or no carry on success. On success they return BC=(9C16), DE=(9C1A), and HL=(9C18). 9C16 = Vendor ID. 9C18 = Device ID. 9C1A = ????.<br />
<br />
<br />
The entry points seem to be called only on initialization and quit. On initialization 5254 then 525D are called, and then 525A six times. On quit, 5254, then 5260, then 5257 are called.<br />
<br />
=== 5254 BCALL ===<br />
The 5254 entry point seems to take a callback address to be passed in A (page) and HL (address). That callback address appears to be called on quit, after 5257 is called.<br />
<br />
=== 5260 and 5257 BCALLs ===<br />
The 5260 and 5257 entry points are called right after each other in the code, and don't seem to take any input. I guess they're some kind of USB shut down. 5260 doesn't do much of anything other than set 9C1E to 0000. 5257 plays with the ports some, and then clears the callback address. Since the call back address gets called, I'm assuming it must also call the callback address somewhere in there.<br />
<br />
=== 525A BCALL ===<br />
525A takes a pointer to a structure in HL. 9C1C will be set to the structure pointer. Some checks on port 4C and 8F are done at teh beginning of this call. A data segment of value: 21 09 0002 0000 0800 will be sent through the control data port. This cooresponds to Host to Device's endpoint, vendor type, set configuration.<br />
<br />
=== 525D BCALL ===<br />
525D takes a pointer to a structure in HL. The 525D entry point first checks to see if bit 3 of port 4C and bits 0 and 2 of port 8F are set. If they are not, it returns failure. These bits are not set by, say, plugging in the hardware. They are set, however, after 5254 has been called. After checking these bits, 9C1E is set to the passed structure pointer. If this value is zero, the routine will return failure. A value of 1 will be stored to HL+2, then a value of 1 will be output to port 8E, a value of 20h to port 94h, and success will be returned.<br />
<br />
=== 5290 BCALL ===<br />
A BCALL to 5290 alone is enough to turn on the LED on EasyTemp. (Though it turns on to a strange orange color which is never seen during EasyData execution). It must do some sort of USB initialization type stuff. If bit 3,(iy+41) is set, 5290 will fail. So this must either be a USB-already-initialized flag, or a Don't-Use-USB flag I guess.<br />
<br />
This BCALL appears to do the following:<br />
# Do stuff<br />
# Request the device descriptor with a maximum size of 8 bytes.<br />
# Issue a Set Address Request, with an address of 2<br />
# Request the device descriptor again, this time with a 18 byte maximum data size.<br />
# Check device description for an appropriate TI or Vernier device and quit if not found.<br />
# Do stuff<br />
<br />
Why are there two device descriptor requests? Presumably so that the calculator can check the peripheral's max packet size (which is in the first 8 bytes), so that it will know how to segmentize further traffic.<br />
<br />
=== 5293 BCALL ===<br />
This BCALL is enough to to turn the LED off on EasyTemp. It's called by 5260.<br />
<br />
=== Other ===<br />
<br />
The callback routine appears to recieve some kind of input in B. I'm not sure what yet.<br />
<br />
<br />
I'm, err, not exactly clear at this point how the app actually gets the temperature data from the EasyTemp probe, as the entry point seem to only be called on init and quit. The callback routine seemed a likely candidate, but it's not that either. Maybe there's something going on in the interrupt that I'm not aware of. Or maybe there are some more entry points used that I missed. ------- I'm now pretty sure that EasyData gets data through the 9C1E structure's callback which I believe returns data retrieved from an interrupt transfer in the OS's interrupt.<br />
<br />
<br />
EasyData is automatically started when you plug the EasyTemp into the USB port if: The current app is Home Screen, a program is not currently executing, and EasyTemp is loaded on the calculator. EasyTemp is searched for via the app header table below.<br />
<br />
==4087 Header==<br />
The calculator knows to run EasyData when the Probe is plugged in because it includes a special header at address 4087h.<br />
The format is as follows:<br />
<nowiki> db 096h, 0E2h, 00h, 01h<br />
dw TablePtr<br />
.....<br />
TablePtr:<br />
dw 1, TableEntryType, DataPtr<br />
.....<br />
DataPtr: ;This is the EasyData data<br />
db 03h, 80h, 03h, 00h, 0F7h, 08h, 02h, 00h<br />
db 80h, 03h, 00h, 0F7h, 08h, 03h, 00h<br />
db 80h, 03h, 00h, 0F7h, 08h, 04h, 00h<br />
db 00h, 00h</nowiki><br />
In theory, the Table should be terminated with a 0000 word. It does not appear that EasyData does this.<br />
<br />
=== Header Table Entries ===<br />
The TableEntryType value can be one of the follow:<br />
*1 - This type is checked for in what seems to be unused OS code. There's a string "IsDevice" that is used in conjunction with it. Perhaps it's an unimplemented feature, or perhaps it's debug code that's not active in the release OS. Your guess is as good as mine.<br />
*2 - This is for the library functions used by OpenLib and ExecLib<br />
*3 - This is for the USB auto-launch, as used by EasyData<br />
<br />
=== USB Data Table ===<br />
If the TableEntryType is 3, then the data will be USB data and will be formatted as follows: The first byte will be the number of entries in the USB data table. Then, each entry, starts with a byte. Not sure what that is. Then comes a word. Not really sure what that is either. But weird things happen if the high byte is not 00. And it appears that if the low byte is 01, only the vendor ID will be checked, if it's 03, the vendor ID and the product ID will be checked. If it's something else, well, something else happens. if the low byte was 03, then the next word will be the vendor ID, and the following word will be the product ID. If both of these match a connected USB device, then the app will launch.<br />
<br />
=== FindSpecialAppHeader BCALL ===<br />
The 50EF BCALL reads the 4087 Header. It is used by the OS. Returns SCF on failure, NC on success. On success, returns in HL the read table value. App name in OP1. Input DE is passed as the table entry to look for. Input A holds whether to look at certain app, or all apps. A = 0 means start at the first app, and search until you find an app with the appropriate header. A = 1 means start searching after the app in OP1. This would be used after the first success returned by A=0, to search the entire app list. A=2 means search only the app named in OP1.<br />
<br />
=== 5263 BCALL ===<br />
The 5263 BCALL reads the 4087 Header. it is used by the OS. This appears to be very similar to the above entry point, except that it searches all the pages by number, instead of searching by name. Input DE = header type to find. Output C on failure, NC on success. HL = table entry value. (appSearchPage) = page it was found on. This only finds the first instance of the header type.<br />
<br />
=== 5266 BCALL ===<br />
This allows you to continue a search you started with the 5263 BCALL. Input page in B.<br />
<br />
=== 5269 BCALL ===<br />
The 5269 BCALL is used by the OS after determining that an app with the USB special app header exists. In general, this entry point seems to compare the values in the USB app header data table with the values at 9C16, 9C18, and 9C1A. Some kind of ID I guess? In specific, it's actually very convoluted and strange code. Input is HL -> data table, A = page.<br />
<br />
== Hardware ==<br />
Ports 55h and 56h are initially polled in the interrupt routine to determine USB activity. If activity is detected, 4Dh, 82h, 84h, 86h, 8Fh, 91h, and others may be polled as well.<br />
<br />
=== Port 4C ===<br />
Some sort of status port. Values of 1A or 5A and 12 or 52 mean something. Default value is 22. Some of the host routines make sure bit 3 is set.<br />
<br />
=== Port 4D ===<br />
Some sort of status port. Bit 4 is set if a type A cable is plugged in. The high nibble appears to be A if nothing is plugged in, and 6 while connected to the computer. The port is checked bit-wise, but I haven't quite figured out how the rest of the bits function yet. I'm as yet unsure whether the values of this port are set based on external events alone, or also influenced by stuff going on in the interrupt. Will check with interrupts disabled later. There is a routine that is called when the bit 1 port 56 event occurs which first waits for bit 6,4D to be reset (which seems like the standard condition after a peripheral has been plugged in). It then does some outputs to ports 3A, 39, 4C, and 8F; after which it waits for bit 6,4D to be set (which seems like the standard condition after a peripheral has been initialized). This doesn't exactly clarify what bit 6 actually means though.<br />
<br />
=== Port 55 ===<br />
This port determines whether there's USB activity for the interrupt routine to take notice of. If any of the first five bits of the port are reset, that means something's happening in USB land. <br />
*bit 0 - Not sure. Only seems to happen with peripheral.<br />
*bit 1 - ???? (not checked by OS)<br />
*bit 2 - Check port 56 for details on what event has happened<br />
*bit 3 - ???? (not checked by OS)<br />
*bit 4 - Data waiting? Or read for data? Or something like this.<br />
<br />
=== Port 56 ===<br />
The default value for port 56h is 00. If bit 2 of port 55 is reset in the interrupt routine, this port should be checked to see what event occured. Each set bit indicates a particular event:<br />
* bit 0 - I've seen this bit set while playing around, but the OS doesn't use it.<br />
* bit 1 - Something to do with peripheral initialization?<br />
* bit 2 - ??<br />
* bit 3 - ??<br />
* bit 4 - Plug-in, A-cable<br />
* bit 5 - Unplug, A-cable<br />
* bit 6 - Plug-in, B-cable<br />
* bit 7 - Unplug, B-cable<br />
<br />
=== Port 5B ===<br />
I think if you load a value of 0 to this port, it will stop the USB controller from issuing interrupts to the calculator. Writing a value of 1 enables USB-related interrupts again.<br />
<br />
=== Port 80 ===<br />
This input/output port holds the address for the device. Valid both when acting as peripheral and when acting as host. (Though the OS always assigns address 2 when acting as host.)<br />
<br />
=== Port 82 ===<br />
Indicates outgoing data success. Seems to be valid both for data packets, and for IN/OUT tokens. Each bit indicates data sent successfully for that Ax port. It seems that the control port's bit registers for both incoming and outgoing data (instead of using port 84).<br />
<br />
=== Port 83 ===<br />
I'm guessing that this is a continuation of port 82, with each bit indicating outgoing data success for endpoint/pipes A8 through AF.<br />
<br />
=== Port 84 ===<br />
Indicates incoming data ready. Each bit indicates data ready to read on that Ax port. The control pipe acts as if it were an out pipe though, so don't expect to see bit 0 set. Check port 82 for control data.<br />
<br />
=== Port 85 ===<br />
I'm guessing that this is a continuation of port 84, with each bit indicating incoming data ready for endpoint/pipes A8 through AF.<br />
<br />
=== Port 86 ===<br />
Some sort of status port. Seems to generally hold a value of 0. Bits 5 or 7 being set seems to be an error condition. Other bits may or may not be error conditions, though it's beginning to look like they'll all errors or abort-conditions of some kind.<br />
<br />
=== Port 87 ===<br />
This port might be a bitmap of which pipes in the Ax range are enabled for output. Port 88 would presumably be a continuation for pipes 8 through F.<br />
<br />
=== Port 89 ===<br />
This port might be a bitmap of which pipes in the Ax range are enabled for input. Port 8A would presumably be a continuation for pipes 8 through F.<br />
<br />
=== Port 8C ===<br />
The low byte of the 15-bit frame counter. It is automatically incremented. I haven't timed it, but in theory it should be incremented about once per millisecond.<br />
<br />
=== Port 8D ===<br />
The high byte of the 15-bit frame counter. See port 8C.<br />
<br />
=== Port 8E ===<br />
This input/output port designates current endpoint to read from/transfer to. Can be 0-15.<br />
<br />
=== Port 8F ===<br />
Values of 1 or 3 are outputted to this port. I have no clue what they mean. After USB init, on read, it seems to be some sort of status. Bit 2 being set appears to imply calculator-as-host, reset seems to imply calculator-as-peripheral. Bit 3 set appears to mean B device, and reset means A device.<br />
<br />
=== Port 90 ===<br />
This port sets up the maximum packet size of outgoing pipes. See port 93.<br />
<br />
=== Port 91 ===<br />
This is the outgoing pipe command port. Port 82h seems to indicate when the command is ready. These bit values are valid in host mode on the control pipe, at least:<br />
* bit 1 - set indicates command in host to device direction, reset indicates from device to host<br />
* bit 3 - set means output data as SETUP packet/token?<br />
* bit 5 - set means output IN token? Reset means OUT token? (compliment of bit 1?)<br />
* bit 6 - reset means there is data associated with this command<br />
So commands for the control pipe would look like:<br />
*Send Control Command (no data)<br />
*# Output SETUP data to port A0<br />
*# Output 0A to port 91 (setup token/data from host to device)<br />
*# Output 60 to port 91 (go to status stage)<br />
*Send Control Command (with incoming data)<br />
*# Output SETUP data to port A0<br />
*# Output 0A to port 91 (setup token/data from host to device)<br />
*# Output 20 to port 91 (request IN data)<br />
*# Read data from port A0<br />
*# Output 42 to port 91 (go to status stage)<br />
*SendControl Command (with outgoing data)<br />
*# Output SETUP data to port A0<br />
*# Output 0A to port 91 (setup token/data from host to device)<br />
*# Output data to port A0<br />
*# Output 02 to port 91 (OUT data)<br />
*# Output 60 to port 91 (go to status stage)<br />
On read, bits 2 or 4 being set indicate an error state. Bit 2 is stall, bit 4 is NAK.<br />
<br />
=== Port 93 ===<br />
This port sets up the maximum packet size for incoming pipes. Multiply the value of the port by 8 to get the packet size. You should probably only set one bit. I have no clue what would happen if you set more than one.<br />
<br />
=== Port 94 ===<br />
This is the incoming pipe command port. Similar to port 91.<br />
<br />
=== Port 96 ===<br />
Holds the low byte of the size of the received and buffered input data for the currently selected endpoint/pipe. Read the data from the appropriate Ax port.<br />
<br />
=== Port 97 ===<br />
Presumably holds the high byte of the size of the received and buffered input data fro the currently selected endpoint/pipe. The 84P doesn't actually send any packets larger than 256 bytes, so it's not used.<br />
<br />
=== Port 98 ===<br />
If the description of port 9A is even remotely right, then this port has a good chance of being the same thing, but for outgoing pipes.<br />
<br />
=== Port 99 ===<br />
While I'm making things up, if ports 98, 9A, and 9B are all correct, then maybe this is the interrupt interval for setup of outgoing interrupt pipes and 9B is incoming interrupt pipes. *shrug*<br />
<br />
=== Port 9A ===<br />
OK, this is quite a strech, long shot, guess, etc; but here are some possibilities for this port: This might set up incoming pipes. The high nibble might define the type of pipe. 2 would be bulk, and 3 would be interrupt. That might make 1 isochronous, but I'm not going to go there. The low nibble might be which pipe to map the current endpoint to. This cooresponds to the port in the AX range. So 21 would map an incoming bulk pipe to port A1h. Or, that could all be completely nonsense. <br />
<br />
=== Port 9B ===<br />
This might setup the poll interval for an interrupt endpoint. Or it might not. Just a thought.<br />
<br />
=== Port A0 ===<br />
This is the control pipe data I/O port. I'm not sure if it's statically fixed this way, or if it is configured like the other pipes.<br />
<br />
=== Ports A1-A? ===<br />
Ports A1 and A2 are used by the OS as data I/O pipes and are set up via port 98 or 9A. It seems likely that more ports in the Ax range can be used as pipes, and I'm guessing all the ports A0-AF can be used.<br />
<br />
== RAM ==<br />
=== 9C13/9C14 ===<br />
9C13 is the page, and 9C14 is the address of a callback routine. It is set by the 5254 BCALL, and called at various times. I'm not really sure what the callback routine is for yet.<br />
<br />
=== 9C16 ===<br />
This is where the vendor ID is stored. It is populated by at least the 5290 BCALL, and perhaps others.<br />
<br />
=== 9C18 ===<br />
This is where the product ID is stored. It is populated by at least the 5290 BCALL, and perhaps others.<br />
<br />
=== 9C1A ===<br />
This is where the device release number is stored. It is populated by at least the 5290 BCALL, and perhaps others.<br />
<br />
=== 9C1C ===<br />
A pointer to another structure. Similar to 9C1E. Output control transfers?<br />
<br />
=== 9C1E ===<br />
A pointer to some sort of structure. First word of structure is a pointer to some sort of receive buffer. Reads from port A1 may be stored here. Perhaps for interrupt transfers? Offset 2 of structure is a byte value. Offset 3 of structure is a callback page and address<br />
<br />
=== 9C26 ===<br />
Byte value representing device state (calc as peripheral)<br />
*0 = Device in default state<br />
*1 = Device in addressed state<br />
*2 = Device in configured state<br />
<br />
=== 9C27 ===<br />
Another byte denoting something about the current state or operation. A value of 1 might imply a host->periph communication and a value of 2 might imply a periph->host communication.<br />
<br />
=== 9C28 ===<br />
Current USB status, or something like that.<br />
*1 = in the middle of USB host initialization<br />
*2 = Background intialization complete?<br />
*3 = Explicit (5290) initialization complete?<br />
*4 =????<br />
*5 = Something to do with uninit?<br />
*6 = Something to do with error states?<br />
<br />
=== 9C29 ===<br />
This is an 8 byte output buffer<br />
<br />
=== 9C31 ===<br />
This is an input buffer of undetermined length. Possibly 64 bytes.<br />
<br />
=== 9C75 ===<br />
A flag byte of some sort. Bits 5, 6, and 7 appear to be used. Bit 5 set means there's outgoing data in a control request (set report). Bit 5 reset means there's incoming data from a control request? Bit 6 reset might indicate that an 84P is connected as a peripheral, set might indicate a Vernier (or perhaps "other") peripheral. Bit seven set might indicate that a Set Address request was just received.<br />
<br />
=== 9C77 ===<br />
Used by the OS to hold the offset in the descriptor table of the descriptor to return.<br />
<br />
=== 9C78 ===<br />
Used by the OS to keep track of how many bytes it needs to send for USB device request replies.<br />
<br />
== Flags ==<br />
Flag byte 41 appears to be the main USB flag. Bit 0 of byte 43 is also used for something related.<br />
<br />
=== 2,(iy+40) ===<br />
If this flag is set, the 82/83 page set might be used for data storage when reading from port A2.<br />
<br />
=== 0,(iy+41) ===<br />
If this flag is set, it will cause a certain part of USB code to abort. This is the code that is called from the interrupt routine when port 55h is 0Fh, and port 56h is 00h. This flag is set in an odd piece of code that loops around an output to port 0A2h. It reads the data to output, however, from RAM pages 02h and 03h. Will have to look into in more detail later.<br />
<br />
=== 2,(iy+41) ===<br />
This flag is set after loading the values of 9C16, 9C18, and 9C1A. But then it's reset if the VID/PID is 0451, E00F. *shrug* In BCALL 5254, it is reset after the bcall to 5290. This bit is checked in Mon, I think.<br />
<br />
=== 3,(iy+41) ===<br />
If set, this means the viewscreen adaptor is connected via USB and has been initialized. If this is set the BCALL 5290 will immediately terminate. Set in Init if device is E00F. At end of init, if flag is set, screen will turn on and be refreshed.<br />
<br />
=== 5,(iy+41) ===<br />
Reset somewhere in USB code. Not sure what it is. This bit is checked in Mon, I think. I think this means there's bulk data to be read.<br />
<br />
=== 6,(iy+41) ===<br />
Reset somewhere in USB code. Not sure what it is.<br />
<br />
=== 7,(iy+41) ===<br />
Reset somewhere in USB code. Not sure what it is.<br />
<br />
== 84 as peripheral USB device requests ==<br />
This section describes the various USB commands that the calculator, acting as a peripheral, will accept. If the calculator receives commands that are not defined below, or if one of the checks designated as "makes sure" fails, it will set 9C84 to FF, and send a value of 60 out endpoint 0. NAK? Stall?<br />
<br />
=== Host to Device @ Device (0) ===<br />
These are commands in the host to device direction, with the device (as opposed to endpoint or interface) as the recipient.<br />
<br />
==== Clear Feature (1) ====<br />
When it receives a 0, 1 Clear Feature command, the calculator first makes sure that an address has been set (9C26 != 0). It also makes sure that the rest of the USB packet is not all zeros, for whatever reason. If processing is completed successfully, a value of 48 will be sent out port 91. WValues accepted as follows:<br />
*1 - According to the USB spec this is Device Remote Wakeup. Sets 9C76 to 0.<br />
*3 - Undefined according to USB spec, but this acts the same as 0,1,1 above.<br />
*5 - Undefined according to USB spec, this makes sure 9C74 is zero, sets 9C73 to zero, and 9C75 to 1.<br />
<br />
==== Set Feature (3) ====<br />
When it receives a 3 Set Feature command, the calculator checks that the rest of the packet is not all zeros. It accepts the following wValues:<br />
*1 - As per USB Spec, Sets Device Remote Wakeup. Sets 9C76 to 2<br />
*3 - Sets 9C73 to 1.<br />
*4 - Sets 9C74 to 1.<br />
*5 - Makes sure 9C74 is 0, and then sets 9C73 to 0 and 9C75 to 1.<br />
<br />
==== Set Address (5) ====<br />
Sets 9C86 to FF. Sets 9C71 to the received address value. (This will later be loaded to port 80). Sets bit 7 of 9C75 (which will indicate later to load the value to port 80). Outputs a value of 1 to port 5B. Outputs a value of 7F to port 87.<br />
<br />
==== Set Configuration (9) ====<br />
Makes sure the device is currently in the address or configured states. Accepts wValues as follows:<br />
* 0 - This will return the device to the address state. Sets 9C26 appropriatly and then outputs 1 to port 5B and FF to port 87.<br />
* 1 - Sets the calculator configuration 1, setting 9C26 appropriatly. Sets endpoint (8E) to 1, outputs 8 to port 90, 48 to port 91, 0 to port 92, 8 to port 93, 90 to port 94, and 0 to port 95. Then sets endpoint to 2, and repeats port outputs.<br />
<br />
=== Host to Device @ Endpoint (2) ===<br />
<br />
==== Clear Feature (1) ====<br />
Clear halt?<br />
<br />
==== Set Feature (3) ====<br />
Set halt?<br />
<br />
=== Device @ Device to Host (80) ===<br />
<br />
==== Get Status (0) ====<br />
Makes sure device is not in the default state. Makes sure packet data is not all zero (possibly with TIOS bug). Makes sure wLength is 2. If 9C76 is 2, responds with two bytes at offset of D5 from descriptor table. Otherwise responds with offset D6. The data seems to be 0,0 either way.<br />
<br />
==== Get Descriptor (6) ====<br />
Returns the requested descriptor. This is complicated. I'll fill in the details later.<br />
<br />
==== Get Configuration (8) ====<br />
Makes sure packet isn't all zeros. Makes sure wLength is 1. If currently in address state, returns 00. Otherwise returns 01.<br />
<br />
=== Device @ Interface to Host (81) ===<br />
<br />
==== Get Status (0) ====<br />
Makes sure the device is not in the default state. Makes sure packet is not all zeros. Makes sure wIndex is 0 and wLength is 2. Responds with 0,0.<br />
<br />
==== Get Interface(A) ====<br />
I'm pretty sure this code is buggy, as it make sure that the device is in the default state, when it ought to be in the configured state. Anyway, after making sure of that and making sure wIndex and wLength are 1, it returns 0.<br />
<br />
=== Device @ Endpoint to Host (82) ===<br />
<br />
==== Get Status (0) ====<br />
Details later...<br />
<br />
== In Other News ==<br />
<br />
=== Stuff ===<br />
* At some point, TI checks for USB devices VID: 045A, PID: E003, E008, and E00F. It seems to return "ok" on E008 and E003, and error on E00F. E008 is the 84P SE. E003 is the 84P. No clue what E00F is. Perhaps the Viewscreen connector?<br />
* I have successfully connected my calculator and digital camera, and retrieved the Product ID and Vendor ID from the camera. Yay :)<br />
* The EasyTemp is an HID device. Haven't figured out the protocol yet.<br />
* For the ever curious: if you have both the serial and USB links connected, the calculator will choose to use the USB link.<br />
* I don't know exactly how much current the calculator can provide, but it can definitely provide enough to power an optical mouse. I managed to turn the mouse on from the calculator, and everything seemed to work fine.<br />
<br />
=== Port Monitor ===<br />
I've written a [http://wikiti.denglend.net/stuff/portmon.8xk Port Monitor] that's been useful for figuring out what some of the ports do. It may be useful for others, but it's not extensively tested, so beware. "Setup Hook" records port data through the USB hook. "Setup Int" records data through an IM2 interrupt (will only take a new sample if a port in the requested range has changed). "Disable Mon" will Stop either the interrupt or hook monitor. "Exec Code" allows you to execute a BCALL or hex code, presumably while one of the monitors is running. Exec program isn't implemented yet. "View Data" allows you to view all the data by sample. "View Changes" allows you to view the data by port, only showing ports that had data changes. In future revisions I may add more monitor triggers through other hooks. Oh, it doesn't read from ports 82 or A0, as these will cause problems with USB activity. The interrupt doesn't read from ports 8C or 8D because these are just counter ports and throw off the sampling.<br />
<br />
=== Mouse ===<br />
So, I've successfully written an HID Mouse driver. One that, amazingly enough, actually works, with both corded and wireless optical mice. Video proof for disbelievers: [http://wikiti.denglend.net/stuff/mouse.avi mouse.avi (7MB)]. Source code will be going on SourceForge sometime in the near future.<br />
<br />
=== USB Protocol ===<br />
This PC<->calc (and presumably calc<->calc) USB protocol is vastly different than the serial protocol. A partial analysis of the protocol can be found [http://users.wpi.edu/~bmoody/usb.txt here].<br />
<br />
=== Presentation Link ===<br />
The presentation link, conjectured to be the E00F device (and E00E for the 89 version) appears to request 16 byte packets? If someone can get ahold of one of these to confirm that, it would be wonderful.<br />
<br />
=== Tested Devices ===<br />
For device compatibility see the [[83Plus:Software:usb8x/Supported_Devices|appropriate page]] in the usb8x documentation.<br />
<br />
=== Alpha version driver available ===<br />
I've released an alpha version of [[83Plus:Software:usb8x|usb8x]], the TI-84 Plus USB driver, on sourceforge. Check out the project's [http://usb8x.sourceforge.net webpage] for downloads and more information. This version provides a host driver-layer for other applications and programs to use, and drivers for USB mouse, USB keyboard, TI's silverlink graphlink, Vernier Easy/Go devices, HID gamepads, and mass storage devices. Keep in mind this is an ALPHA version, and many things will probably change before the final release. In other words, don't release any programs that rely on the current driver-layer.<br />
<br />
[[Category:83Plus:OS_Information|84 Plus USB Information]]</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=83Plus:OS:84_Plus_USB_Information83Plus:OS:84 Plus USB Information2006-11-01T17:09:08Z<p>Dan Englender: /* Port 87 */ output ports</p>
<hr />
<div>:I moved this page from Talk:83Plus:BCALLs:5254 to here because it seems to fit better. Please note that this is still a work in progress, and don't take the information as gold. I figured having an option for a Talk page for this would outweigh the moving of it. For the time being, we'll leave the data formatted as-is, since it's still nicely done. --[[User:AndyJ|AndyJ]] 07:44, 27 May 2005 (PDT)<br />
<br />
<br />
<br />
OK, I've started this talk page to post information about the 84 Plus USB. This isn't the ideal place, since not all of this stuff has to do with entry point 5254, but it'll have to do. If anyone else would like to contribute any information or thoughts, please do so. Much of this data has been discovered by analyzing how the EasyData application interacts with the EasyTemp probe. --[[User:Dan Englender|Dan Englender]] 22:32, 23 May 2005 (PDT)<br />
<br />
Many thanks to Olivier Armand for providing information invaluable to figuring out some of the harder to decipher USB ports. --[[User:Dan Englender|Dan Englender]] 23:25, 9 Jul 2005 (PDT)<br />
<br />
== Easy Data ==<br />
The USB entry points that Easy Data uses are:<br />
5254<br />
5257<br />
525A<br />
525D<br />
5260<br />
<br />
These routines return carry flag with an error code in A on failure, or no carry on success. On success they return BC=(9C16), DE=(9C1A), and HL=(9C18). 9C16 = Vendor ID. 9C18 = Device ID. 9C1A = ????.<br />
<br />
<br />
The entry points seem to be called only on initialization and quit. On initialization 5254 then 525D are called, and then 525A six times. On quit, 5254, then 5260, then 5257 are called.<br />
<br />
=== 5254 BCALL ===<br />
The 5254 entry point seems to take a callback address to be passed in A (page) and HL (address). That callback address appears to be called on quit, after 5257 is called.<br />
<br />
=== 5260 and 5257 BCALLs ===<br />
The 5260 and 5257 entry points are called right after each other in the code, and don't seem to take any input. I guess they're some kind of USB shut down. 5260 doesn't do much of anything other than set 9C1E to 0000. 5257 plays with the ports some, and then clears the callback address. Since the call back address gets called, I'm assuming it must also call the callback address somewhere in there.<br />
<br />
=== 525A BCALL ===<br />
525A takes a pointer to a structure in HL. 9C1C will be set to the structure pointer. Some checks on port 4C and 8F are done at teh beginning of this call. A data segment of value: 21 09 0002 0000 0800 will be sent through the control data port. This cooresponds to Host to Device's endpoint, vendor type, set configuration.<br />
<br />
=== 525D BCALL ===<br />
525D takes a pointer to a structure in HL. The 525D entry point first checks to see if bit 3 of port 4C and bits 0 and 2 of port 8F are set. If they are not, it returns failure. These bits are not set by, say, plugging in the hardware. They are set, however, after 5254 has been called. After checking these bits, 9C1E is set to the passed structure pointer. If this value is zero, the routine will return failure. A value of 1 will be stored to HL+2, then a value of 1 will be output to port 8E, a value of 20h to port 94h, and success will be returned.<br />
<br />
=== 5290 BCALL ===<br />
A BCALL to 5290 alone is enough to turn on the LED on EasyTemp. (Though it turns on to a strange orange color which is never seen during EasyData execution). It must do some sort of USB initialization type stuff. If bit 3,(iy+41) is set, 5290 will fail. So this must either be a USB-already-initialized flag, or a Don't-Use-USB flag I guess.<br />
<br />
This BCALL appears to do the following:<br />
# Do stuff<br />
# Request the device descriptor with a maximum size of 8 bytes.<br />
# Issue a Set Address Request, with an address of 2<br />
# Request the device descriptor again, this time with a 18 byte maximum data size.<br />
# Check device description for an appropriate TI or Vernier device and quit if not found.<br />
# Do stuff<br />
<br />
Why are there two device descriptor requests? Presumably so that the calculator can check the peripheral's max packet size (which is in the first 8 bytes), so that it will know how to segmentize further traffic.<br />
<br />
=== 5293 BCALL ===<br />
This BCALL is enough to to turn the LED off on EasyTemp. It's called by 5260.<br />
<br />
=== Other ===<br />
<br />
The callback routine appears to recieve some kind of input in B. I'm not sure what yet.<br />
<br />
<br />
I'm, err, not exactly clear at this point how the app actually gets the temperature data from the EasyTemp probe, as the entry point seem to only be called on init and quit. The callback routine seemed a likely candidate, but it's not that either. Maybe there's something going on in the interrupt that I'm not aware of. Or maybe there are some more entry points used that I missed. ------- I'm now pretty sure that EasyData gets data through the 9C1E structure's callback which I believe returns data retrieved from an interrupt transfer in the OS's interrupt.<br />
<br />
<br />
EasyData is automatically started when you plug the EasyTemp into the USB port if: The current app is Home Screen, a program is not currently executing, and EasyTemp is loaded on the calculator. EasyTemp is searched for via the app header table below.<br />
<br />
==4087 Header==<br />
The calculator knows to run EasyData when the Probe is plugged in because it includes a special header at address 4087h.<br />
The format is as follows:<br />
<nowiki> db 096h, 0E2h, 00h, 01h<br />
dw TablePtr<br />
.....<br />
TablePtr:<br />
dw 1, TableEntryType, DataPtr<br />
.....<br />
DataPtr: ;This is the EasyData data<br />
db 03h, 80h, 03h, 00h, 0F7h, 08h, 02h, 00h<br />
db 80h, 03h, 00h, 0F7h, 08h, 03h, 00h<br />
db 80h, 03h, 00h, 0F7h, 08h, 04h, 00h<br />
db 00h, 00h</nowiki><br />
In theory, the Table should be terminated with a 0000 word. It does not appear that EasyData does this.<br />
<br />
=== Header Table Entries ===<br />
The TableEntryType value can be one of the follow:<br />
*1 - This type is checked for in what seems to be unused OS code. There's a string "IsDevice" that is used in conjunction with it. Perhaps it's an unimplemented feature, or perhaps it's debug code that's not active in the release OS. Your guess is as good as mine.<br />
*2 - This is for the library functions used by OpenLib and ExecLib<br />
*3 - This is for the USB auto-launch, as used by EasyData<br />
<br />
=== USB Data Table ===<br />
If the TableEntryType is 3, then the data will be USB data and will be formatted as follows: The first byte will be the number of entries in the USB data table. Then, each entry, starts with a byte. Not sure what that is. Then comes a word. Not really sure what that is either. But weird things happen if the high byte is not 00. And it appears that if the low byte is 01, only the vendor ID will be checked, if it's 03, the vendor ID and the product ID will be checked. If it's something else, well, something else happens. if the low byte was 03, then the next word will be the vendor ID, and the following word will be the product ID. If both of these match a connected USB device, then the app will launch.<br />
<br />
=== FindSpecialAppHeader BCALL ===<br />
The 50EF BCALL reads the 4087 Header. It is used by the OS. Returns SCF on failure, NC on success. On success, returns in HL the read table value. App name in OP1. Input DE is passed as the table entry to look for. Input A holds whether to look at certain app, or all apps. A = 0 means start at the first app, and search until you find an app with the appropriate header. A = 1 means start searching after the app in OP1. This would be used after the first success returned by A=0, to search the entire app list. A=2 means search only the app named in OP1.<br />
<br />
=== 5263 BCALL ===<br />
The 5263 BCALL reads the 4087 Header. it is used by the OS. This appears to be very similar to the above entry point, except that it searches all the pages by number, instead of searching by name. Input DE = header type to find. Output C on failure, NC on success. HL = table entry value. (appSearchPage) = page it was found on. This only finds the first instance of the header type.<br />
<br />
=== 5266 BCALL ===<br />
This allows you to continue a search you started with the 5263 BCALL. Input page in B.<br />
<br />
=== 5269 BCALL ===<br />
The 5269 BCALL is used by the OS after determining that an app with the USB special app header exists. In general, this entry point seems to compare the values in the USB app header data table with the values at 9C16, 9C18, and 9C1A. Some kind of ID I guess? In specific, it's actually very convoluted and strange code. Input is HL -> data table, A = page.<br />
<br />
== Hardware ==<br />
Ports 55h and 56h are initially polled in the interrupt routine to determine USB activity. If activity is detected, 4Dh, 82h, 84h, 86h, 8Fh, 91h, and others may be polled as well.<br />
<br />
=== Port 4C ===<br />
Some sort of status port. Values of 1A or 5A and 12 or 52 mean something. Default value is 22. Some of the host routines make sure bit 3 is set.<br />
<br />
=== Port 4D ===<br />
Some sort of status port. Bit 4 is set if a type A cable is plugged in. The high nibble appears to be A if nothing is plugged in, and 6 while connected to the computer. The port is checked bit-wise, but I haven't quite figured out how the rest of the bits function yet. I'm as yet unsure whether the values of this port are set based on external events alone, or also influenced by stuff going on in the interrupt. Will check with interrupts disabled later. There is a routine that is called when the bit 1 port 56 event occurs which first waits for bit 6,4D to be reset (which seems like the standard condition after a peripheral has been plugged in). It then does some outputs to ports 3A, 39, 4C, and 8F; after which it waits for bit 6,4D to be set (which seems like the standard condition after a peripheral has been initialized). This doesn't exactly clarify what bit 6 actually means though.<br />
<br />
=== Port 55 ===<br />
This port determines whether there's USB activity for the interrupt routine to take notice of. If any of the first five bits of the port are reset, that means something's happening in USB land. <br />
*bit 0 - Not sure. Only seems to happen with peripheral.<br />
*bit 1 - ???? (not checked by OS)<br />
*bit 2 - Check port 56 for details on what event has happened<br />
*bit 3 - ???? (not checked by OS)<br />
*bit 4 - Data waiting? Or read for data? Or something like this.<br />
<br />
=== Port 56 ===<br />
The default value for port 56h is 00. If bit 2 of port 55 is reset in the interrupt routine, this port should be checked to see what event occured. Each set bit indicates a particular event:<br />
* bit 0 - I've seen this bit set while playing around, but the OS doesn't use it.<br />
* bit 1 - Something to do with peripheral initialization?<br />
* bit 2 - ??<br />
* bit 3 - ??<br />
* bit 4 - Plug-in, A-cable<br />
* bit 5 - Unplug, A-cable<br />
* bit 6 - Plug-in, B-cable<br />
* bit 7 - Unplug, B-cable<br />
<br />
=== Port 5B ===<br />
I think if you load a value of 0 to this port, it will stop the USB controller from issuing interrupts to the calculator. Writing a value of 1 enables USB-related interrupts again.<br />
<br />
=== Port 80 ===<br />
This input/output port holds the address for the device. Valid both when acting as peripheral and when acting as host. (Though the OS always assigns address 2 when acting as host.)<br />
<br />
=== Port 82 ===<br />
Indicates outgoing data success. Seems to be valid both for data packets, and for IN/OUT tokens. Each bit indicates data sent successfully for that Ax port. It seems that the control port's bit registers for both incoming and outgoing data (instead of using port 84).<br />
<br />
=== Port 83 ===<br />
I'm guessing that this is a continuation of port 82, with each bit indicating outgoing data success for endpoint/pipes A8 through AF.<br />
<br />
=== Port 84 ===<br />
Indicates incoming data ready. Each bit indicates data ready to read on that Ax port. The control pipe acts as if it were an out pipe though, so don't expect to see bit 0 set. Check port 82 for control data.<br />
<br />
=== Port 85 ===<br />
I'm guessing that this is a continuation of port 84, with each bit indicating incoming data ready for endpoint/pipes A8 through AF.<br />
<br />
=== Port 86 ===<br />
Some sort of status port. Seems to generally hold a value of 0. Bits 5 or 7 being set seems to be an error condition. Other bits may or may not be error conditions, though it's beginning to look like they'll all errors or abort-conditions of some kind.<br />
<br />
=== Port 87 ===<br />
This port might be a bitmap of which pipes in the Ax range are enabled for output. Port 88 would presumably be a continuation for pipes 8-15.<br />
<br />
=== Port 8C ===<br />
The low byte of the 15-bit frame counter. It is automatically incremented. I haven't timed it, but in theory it should be incremented about once per millisecond.<br />
<br />
=== Port 8D ===<br />
The high byte of the 15-bit frame counter. See port 8C.<br />
<br />
=== Port 8E ===<br />
This input/output port designates current endpoint to read from/transfer to. Can be 0-15.<br />
<br />
=== Port 8F ===<br />
Values of 1 or 3 are outputted to this port. I have no clue what they mean. After USB init, on read, it seems to be some sort of status. Bit 2 being set appears to imply calculator-as-host, reset seems to imply calculator-as-peripheral. Bit 3 set appears to mean B device, and reset means A device.<br />
<br />
=== Port 90 ===<br />
This port sets up the maximum packet size of outgoing pipes. See port 93.<br />
<br />
=== Port 91 ===<br />
This is the outgoing pipe command port. Port 82h seems to indicate when the command is ready. These bit values are valid in host mode on the control pipe, at least:<br />
* bit 1 - set indicates command in host to device direction, reset indicates from device to host<br />
* bit 3 - set means output data as SETUP packet/token?<br />
* bit 5 - set means output IN token? Reset means OUT token? (compliment of bit 1?)<br />
* bit 6 - reset means there is data associated with this command<br />
So commands for the control pipe would look like:<br />
*Send Control Command (no data)<br />
*# Output SETUP data to port A0<br />
*# Output 0A to port 91 (setup token/data from host to device)<br />
*# Output 60 to port 91 (go to status stage)<br />
*Send Control Command (with incoming data)<br />
*# Output SETUP data to port A0<br />
*# Output 0A to port 91 (setup token/data from host to device)<br />
*# Output 20 to port 91 (request IN data)<br />
*# Read data from port A0<br />
*# Output 42 to port 91 (go to status stage)<br />
*SendControl Command (with outgoing data)<br />
*# Output SETUP data to port A0<br />
*# Output 0A to port 91 (setup token/data from host to device)<br />
*# Output data to port A0<br />
*# Output 02 to port 91 (OUT data)<br />
*# Output 60 to port 91 (go to status stage)<br />
On read, bits 2 or 4 being set indicate an error state. Bit 2 is stall, bit 4 is NAK.<br />
<br />
=== Port 93 ===<br />
This port sets up the maximum packet size for incoming pipes. Multiply the value of the port by 8 to get the packet size. You should probably only set one bit. I have no clue what would happen if you set more than one.<br />
<br />
=== Port 94 ===<br />
This is the incoming pipe command port. Similar to port 91.<br />
<br />
=== Port 96 ===<br />
Holds the low byte of the size of the received and buffered input data for the currently selected endpoint/pipe. Read the data from the appropriate Ax port.<br />
<br />
=== Port 97 ===<br />
Presumably holds the high byte of the size of the received and buffered input data fro the currently selected endpoint/pipe. The 84P doesn't actually send any packets larger than 256 bytes, so it's not used.<br />
<br />
=== Port 98 ===<br />
If the description of port 9A is even remotely right, then this port has a good chance of being the same thing, but for outgoing pipes.<br />
<br />
=== Port 99 ===<br />
While I'm making things up, if ports 98, 9A, and 9B are all correct, then maybe this is the interrupt interval for setup of outgoing interrupt pipes and 9B is incoming interrupt pipes. *shrug*<br />
<br />
=== Port 9A ===<br />
OK, this is quite a strech, long shot, guess, etc; but here are some possibilities for this port: This might set up incoming pipes. The high nibble might define the type of pipe. 2 would be bulk, and 3 would be interrupt. That might make 1 isochronous, but I'm not going to go there. The low nibble might be which pipe to map the current endpoint to. This cooresponds to the port in the AX range. So 21 would map an incoming bulk pipe to port A1h. Or, that could all be completely nonsense. <br />
<br />
=== Port 9B ===<br />
This might setup the poll interval for an interrupt endpoint. Or it might not. Just a thought.<br />
<br />
=== Port A0 ===<br />
This is the control pipe data I/O port. I'm not sure if it's statically fixed this way, or if it is configured like the other pipes.<br />
<br />
=== Ports A1-A? ===<br />
Ports A1 and A2 are used by the OS as data I/O pipes and are set up via port 98 or 9A. It seems likely that more ports in the Ax range can be used as pipes, and I'm guessing all the ports A0-AF can be used.<br />
<br />
== RAM ==<br />
=== 9C13/9C14 ===<br />
9C13 is the page, and 9C14 is the address of a callback routine. It is set by the 5254 BCALL, and called at various times. I'm not really sure what the callback routine is for yet.<br />
<br />
=== 9C16 ===<br />
This is where the vendor ID is stored. It is populated by at least the 5290 BCALL, and perhaps others.<br />
<br />
=== 9C18 ===<br />
This is where the product ID is stored. It is populated by at least the 5290 BCALL, and perhaps others.<br />
<br />
=== 9C1A ===<br />
This is where the device release number is stored. It is populated by at least the 5290 BCALL, and perhaps others.<br />
<br />
=== 9C1C ===<br />
A pointer to another structure. Similar to 9C1E. Output control transfers?<br />
<br />
=== 9C1E ===<br />
A pointer to some sort of structure. First word of structure is a pointer to some sort of receive buffer. Reads from port A1 may be stored here. Perhaps for interrupt transfers? Offset 2 of structure is a byte value. Offset 3 of structure is a callback page and address<br />
<br />
=== 9C26 ===<br />
Byte value representing device state (calc as peripheral)<br />
*0 = Device in default state<br />
*1 = Device in addressed state<br />
*2 = Device in configured state<br />
<br />
=== 9C27 ===<br />
Another byte denoting something about the current state or operation. A value of 1 might imply a host->periph communication and a value of 2 might imply a periph->host communication.<br />
<br />
=== 9C28 ===<br />
Current USB status, or something like that.<br />
*1 = in the middle of USB host initialization<br />
*2 = Background intialization complete?<br />
*3 = Explicit (5290) initialization complete?<br />
*4 =????<br />
*5 = Something to do with uninit?<br />
*6 = Something to do with error states?<br />
<br />
=== 9C29 ===<br />
This is an 8 byte output buffer<br />
<br />
=== 9C31 ===<br />
This is an input buffer of undetermined length. Possibly 64 bytes.<br />
<br />
=== 9C75 ===<br />
A flag byte of some sort. Bits 5, 6, and 7 appear to be used. Bit 5 set means there's outgoing data in a control request (set report). Bit 5 reset means there's incoming data from a control request? Bit 6 reset might indicate that an 84P is connected as a peripheral, set might indicate a Vernier (or perhaps "other") peripheral. Bit seven set might indicate that a Set Address request was just received.<br />
<br />
=== 9C77 ===<br />
Used by the OS to hold the offset in the descriptor table of the descriptor to return.<br />
<br />
=== 9C78 ===<br />
Used by the OS to keep track of how many bytes it needs to send for USB device request replies.<br />
<br />
== Flags ==<br />
Flag byte 41 appears to be the main USB flag. Bit 0 of byte 43 is also used for something related.<br />
<br />
=== 2,(iy+40) ===<br />
If this flag is set, the 82/83 page set might be used for data storage when reading from port A2.<br />
<br />
=== 0,(iy+41) ===<br />
If this flag is set, it will cause a certain part of USB code to abort. This is the code that is called from the interrupt routine when port 55h is 0Fh, and port 56h is 00h. This flag is set in an odd piece of code that loops around an output to port 0A2h. It reads the data to output, however, from RAM pages 02h and 03h. Will have to look into in more detail later.<br />
<br />
=== 2,(iy+41) ===<br />
This flag is set after loading the values of 9C16, 9C18, and 9C1A. But then it's reset if the VID/PID is 0451, E00F. *shrug* In BCALL 5254, it is reset after the bcall to 5290. This bit is checked in Mon, I think.<br />
<br />
=== 3,(iy+41) ===<br />
If set, this means the viewscreen adaptor is connected via USB and has been initialized. If this is set the BCALL 5290 will immediately terminate. Set in Init if device is E00F. At end of init, if flag is set, screen will turn on and be refreshed.<br />
<br />
=== 5,(iy+41) ===<br />
Reset somewhere in USB code. Not sure what it is. This bit is checked in Mon, I think. I think this means there's bulk data to be read.<br />
<br />
=== 6,(iy+41) ===<br />
Reset somewhere in USB code. Not sure what it is.<br />
<br />
=== 7,(iy+41) ===<br />
Reset somewhere in USB code. Not sure what it is.<br />
<br />
== 84 as peripheral USB device requests ==<br />
This section describes the various USB commands that the calculator, acting as a peripheral, will accept. If the calculator receives commands that are not defined below, or if one of the checks designated as "makes sure" fails, it will set 9C84 to FF, and send a value of 60 out endpoint 0. NAK? Stall?<br />
<br />
=== Host to Device @ Device (0) ===<br />
These are commands in the host to device direction, with the device (as opposed to endpoint or interface) as the recipient.<br />
<br />
==== Clear Feature (1) ====<br />
When it receives a 0, 1 Clear Feature command, the calculator first makes sure that an address has been set (9C26 != 0). It also makes sure that the rest of the USB packet is not all zeros, for whatever reason. If processing is completed successfully, a value of 48 will be sent out port 91. WValues accepted as follows:<br />
*1 - According to the USB spec this is Device Remote Wakeup. Sets 9C76 to 0.<br />
*3 - Undefined according to USB spec, but this acts the same as 0,1,1 above.<br />
*5 - Undefined according to USB spec, this makes sure 9C74 is zero, sets 9C73 to zero, and 9C75 to 1.<br />
<br />
==== Set Feature (3) ====<br />
When it receives a 3 Set Feature command, the calculator checks that the rest of the packet is not all zeros. It accepts the following wValues:<br />
*1 - As per USB Spec, Sets Device Remote Wakeup. Sets 9C76 to 2<br />
*3 - Sets 9C73 to 1.<br />
*4 - Sets 9C74 to 1.<br />
*5 - Makes sure 9C74 is 0, and then sets 9C73 to 0 and 9C75 to 1.<br />
<br />
==== Set Address (5) ====<br />
Sets 9C86 to FF. Sets 9C71 to the received address value. (This will later be loaded to port 80). Sets bit 7 of 9C75 (which will indicate later to load the value to port 80). Outputs a value of 1 to port 5B. Outputs a value of 7F to port 87.<br />
<br />
==== Set Configuration (9) ====<br />
Makes sure the device is currently in the address or configured states. Accepts wValues as follows:<br />
* 0 - This will return the device to the address state. Sets 9C26 appropriatly and then outputs 1 to port 5B and FF to port 87.<br />
* 1 - Sets the calculator configuration 1, setting 9C26 appropriatly. Sets endpoint (8E) to 1, outputs 8 to port 90, 48 to port 91, 0 to port 92, 8 to port 93, 90 to port 94, and 0 to port 95. Then sets endpoint to 2, and repeats port outputs.<br />
<br />
=== Host to Device @ Endpoint (2) ===<br />
<br />
==== Clear Feature (1) ====<br />
Clear halt?<br />
<br />
==== Set Feature (3) ====<br />
Set halt?<br />
<br />
=== Device @ Device to Host (80) ===<br />
<br />
==== Get Status (0) ====<br />
Makes sure device is not in the default state. Makes sure packet data is not all zero (possibly with TIOS bug). Makes sure wLength is 2. If 9C76 is 2, responds with two bytes at offset of D5 from descriptor table. Otherwise responds with offset D6. The data seems to be 0,0 either way.<br />
<br />
==== Get Descriptor (6) ====<br />
Returns the requested descriptor. This is complicated. I'll fill in the details later.<br />
<br />
==== Get Configuration (8) ====<br />
Makes sure packet isn't all zeros. Makes sure wLength is 1. If currently in address state, returns 00. Otherwise returns 01.<br />
<br />
=== Device @ Interface to Host (81) ===<br />
<br />
==== Get Status (0) ====<br />
Makes sure the device is not in the default state. Makes sure packet is not all zeros. Makes sure wIndex is 0 and wLength is 2. Responds with 0,0.<br />
<br />
==== Get Interface(A) ====<br />
I'm pretty sure this code is buggy, as it make sure that the device is in the default state, when it ought to be in the configured state. Anyway, after making sure of that and making sure wIndex and wLength are 1, it returns 0.<br />
<br />
=== Device @ Endpoint to Host (82) ===<br />
<br />
==== Get Status (0) ====<br />
Details later...<br />
<br />
== In Other News ==<br />
<br />
=== Stuff ===<br />
* At some point, TI checks for USB devices VID: 045A, PID: E003, E008, and E00F. It seems to return "ok" on E008 and E003, and error on E00F. E008 is the 84P SE. E003 is the 84P. No clue what E00F is. Perhaps the Viewscreen connector?<br />
* I have successfully connected my calculator and digital camera, and retrieved the Product ID and Vendor ID from the camera. Yay :)<br />
* The EasyTemp is an HID device. Haven't figured out the protocol yet.<br />
* For the ever curious: if you have both the serial and USB links connected, the calculator will choose to use the USB link.<br />
* I don't know exactly how much current the calculator can provide, but it can definitely provide enough to power an optical mouse. I managed to turn the mouse on from the calculator, and everything seemed to work fine.<br />
<br />
=== Port Monitor ===<br />
I've written a [http://wikiti.denglend.net/stuff/portmon.8xk Port Monitor] that's been useful for figuring out what some of the ports do. It may be useful for others, but it's not extensively tested, so beware. "Setup Hook" records port data through the USB hook. "Setup Int" records data through an IM2 interrupt (will only take a new sample if a port in the requested range has changed). "Disable Mon" will Stop either the interrupt or hook monitor. "Exec Code" allows you to execute a BCALL or hex code, presumably while one of the monitors is running. Exec program isn't implemented yet. "View Data" allows you to view all the data by sample. "View Changes" allows you to view the data by port, only showing ports that had data changes. In future revisions I may add more monitor triggers through other hooks. Oh, it doesn't read from ports 82 or A0, as these will cause problems with USB activity. The interrupt doesn't read from ports 8C or 8D because these are just counter ports and throw off the sampling.<br />
<br />
=== Mouse ===<br />
So, I've successfully written an HID Mouse driver. One that, amazingly enough, actually works, with both corded and wireless optical mice. Video proof for disbelievers: [http://wikiti.denglend.net/stuff/mouse.avi mouse.avi (7MB)]. Source code will be going on SourceForge sometime in the near future.<br />
<br />
=== USB Protocol ===<br />
This PC<->calc (and presumably calc<->calc) USB protocol is vastly different than the serial protocol. A partial analysis of the protocol can be found [http://users.wpi.edu/~bmoody/usb.txt here].<br />
<br />
=== Presentation Link ===<br />
The presentation link, conjectured to be the E00F device (and E00E for the 89 version) appears to request 16 byte packets? If someone can get ahold of one of these to confirm that, it would be wonderful.<br />
<br />
=== Tested Devices ===<br />
For device compatibility see the [[83Plus:Software:usb8x/Supported_Devices|appropriate page]] in the usb8x documentation.<br />
<br />
=== Alpha version driver available ===<br />
I've released an alpha version of [[83Plus:Software:usb8x|usb8x]], the TI-84 Plus USB driver, on sourceforge. Check out the project's [http://usb8x.sourceforge.net webpage] for downloads and more information. This version provides a host driver-layer for other applications and programs to use, and drivers for USB mouse, USB keyboard, TI's silverlink graphlink, Vernier Easy/Go devices, HID gamepads, and mass storage devices. Keep in mind this is an ALPHA version, and many things will probably change before the final release. In other words, don't release any programs that rely on the current driver-layer.<br />
<br />
[[Category:83Plus:OS_Information|84 Plus USB Information]]</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=83Plus:Software:usb8x/Build83Plus:Software:usb8x/Build2006-10-21T21:40:28Z<p>Dan Englender: typo</p>
<hr />
<div>Building usb8x from source is (hopefully) an easy process. You need [http://www.zilog.com/tools/software.asp ZDS] or a ZDS-compatible assembler. Just open the usb8x.zws project file in ZDS and compile to produce a .hex file which you can sign with wappsign or your favorite signing tool.<br />
<br />
Compile time settings are listed in settings.inc. They are:<br />
{| border="1" cellpadding="2" cellspacing="0" <br />
!Setting Name !! Default !! Description<br />
|-<br />
|LOGGING_ON || 0 || If set to 1, logging support will be compiled. Even if logging support is compiled, logs will not actually be kept unless [[../Asm_Interface/SetupLog|SetupLog]] is called. Logging support, even if logging is not enabled, can significantly slow down high speed drivers like MSD, so logging support should be disabled except in debug versions.<br />
|-<br />
|ASSERT_ON || 0 || If set to 1, assertion support will be compiled. Assertions are used throughout the usb8x code to make sure certain inputs and outputs are within reasonable bounds. If they are not the assertion is triggered, debug information is displayed on the screen, and the calculator halts. Assertions slightly slow down usb8x operation, so they should probably be disabled in release versions.<br />
|-<br />
|SAFETYINT_ON || 0 || If set to 1, an safety interrupt will be compiled and automatically loaded when the driver is started. This interrupt checks memory for sane values using assertions. Thus, if you enable the safety interrupt, you should also enable assertions. The safety interrupt uses statVars, so it should be disabled in release versions to prevent conflicts with external software.<br />
|-<br />
|HUBCODE_ON || 0 || If set to 1, code for handling USB hubs will be compiled. This code provides routines to set and clear hub features, and also causes AutoSetup to automatically bypass an attached hub and instead setup the first attached device. The current code only works with some devices (doesn't work with HID devices) so it is disabled by default.<br />
|-<br />
|CACHE_ON || 1 || If set to 1, code for MSD caching is compiled. Even if caching support is compiled, the cache will not be active unless the external program using the MSD driver specifically enables it. Current cache code should be bug-free for reads, but may still have some bugs when writing.<br />
|-<br />
|VERNIER_ON / KBD_ON / MOUSE_ON / MSD_ON / SILVER_ON / PAD_ON || 1 || If set to 1, the cooresponding driver will be compiled. The release version of usb8x includes all drivers. If a driver is not compiled and an external program tries to access it, a FeatureDisabled error will be returned.<br />
|-<br />
|ALWAYSCANCELINT_ON || 0 || If set to 1, the usb8x interrupt will always tell the TIOS to ignore USB events, even if the event is something that usb8x does not handle. <br />
|-<br />
|INTERRUPTMACRO_TYPE || 1 || If set to 0, usb8x will not disable or enable interrupts around sensitive routines. If set to 1, usb8x will disable and enable interrupts with di/ei around sensitive routines. If set to 2, usb8x will save the status of the interrupt before disabling it, and only re-enable interrupts if they were on to begin with. Set to 1 by default because it seems to work the best.<br />
|-<br />
|LOGxxxxxx_ON || 1 || Each of the many log settings controls one particular log file type. If a log setting is seto to 1, then the cooresponding log type will be included in the log file (assuming logging is compiled and enabled). If set to 0, that log type will be ignored. These settings are good if you're debugging one particular system and don't want the log file to be cluttered up with extraneous information.<br />
|}</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=83Plus:Software:usb8x/Build83Plus:Software:usb8x/Build2006-10-21T20:53:54Z<p>Dan Englender: </p>
<hr />
<div>Building usb8x from source is (hopefully) an easy process. You need [http://www.zilog.com/tools/software.asp ZDS] or a ZDS-compatible assembler. Just open the usb8x.zws project file in ZDS and compile to produce a .hex file which you can sign with wappsign or your favorite signing tool.<br />
<br />
Compile time settings are listed in settings.inc. They are:<br />
{| border="1" cellpadding="2" cellspacing="0" <br />
!Setting Name !! Default !! Description<br />
|-<br />
|LOGGING_ON || 0 || If set to 1, logging support will be compiled. Even if logging support is compiled, logs will not actually be kept unless [[../Asm_Interface/SetupLog|SetupLog]] is called. Logging support, even if logging is not enabled, can significantly slow down high speed drivers like MSD, so logging support should be disabled except in debug versions.<br />
|-<br />
|ASSERT_ON || 0 || If set to 1, assertion support will be compiled. Assertions are used throughout the usb8x code to make sure certain inputs and outputs are within reasonable bounds. If they are not the assertion is triggered, debug information is displayed on the screen, and the calculator halts. Assertions slightly slow down usb8x operation, so they should probably be disabled in release versions.<br />
|-<br />
|SAFETYINT_ON || 0 || If set to 1, an safety interrupt will be compiled and automatically loaded when the drive is started. This interrupt checks memory for sane values using assertions. Thus, if you enable the safety interrupt, you should also enable assertions. The safety interrupt uses statVars, so it should be disabled in release versions to prevent conflicts with external software.<br />
|-<br />
|HUBCODE_ON || 0 || If set to 1, code for handling USB hubs will be compiled. This code provides routines to set and clear hub features, and also causes AutoSetup to automatically bypass an attached hub and instead setup the first attached device. The current code only works with some devices (doesn't work with HID devices) so it is disabled by default.<br />
|-<br />
|CACHE_ON || 1 || If set to 1, code for MSD caching is compiled. Even if caching support is compiled, the cache will not be active unless the external program using the MSD driver specifically enables it. Current cache code should be bug-free for reads, but may still have some bugs when writing.<br />
|-<br />
|VERNIER_ON / KBD_ON / MOUSE_ON / MSD_ON / SILVER_ON / PAD_ON || 1 || If set to 1, the cooresponding driver will be compiled. The release version of usb8x includes all drivers. If a driver is not compiled and an external program tries to access it, a FeatureDisabled error will be returned.<br />
|-<br />
|ALWAYSCANCELINT_ON || 0 || If set to 1, the usb8x interrupt will always tell the TIOS to ignore USB events, even if the event is something that usb8x does not handle. <br />
|-<br />
|INTERRUPTMACRO_TYPE || 1 || If set to 0, usb8x will not disable or enable interrupts around sensitive routines. If set to 1, usb8x will disable and enable interrupts with di/ei around sensitive routines. If set to 2, usb8x will save the status of the interrupt before disabling it, and only re-enable interrupts if they were on to begin with. Set to 1 by default because it seems to work the best.<br />
|-<br />
|LOGxxxxxx_ON || 1 || Each of the many log settings controls one particular log file type. If a log setting is seto to 1, then the cooresponding log type will be included in the log file (assuming logging is compiled and enabled). If set to 0, that log type will be ignored. These settings are good if you're debugging one particular system and don't want the log file to be cluttered up with extraneous information.<br />
|}</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=83Plus:Software:usb8x83Plus:Software:usb8x2006-10-21T20:26:57Z<p>Dan Englender: Reoganized again.</p>
<hr />
<div>usb8x is a free, open source application for the TI-84 Plus calculators. It combines a low level driver to support the calculator's USB port with a limited selection of device drivers. It is designed with two goals in mind: First, to allow programmers to create external applications/programs that use USB devices without any knowledge of the low-level workings of those devices or the USB port itself. Second, to allow programmers to create additional drivers for other USB hardware not currently supported natively in usb8x.<br />
<br />
The current release version of usb8x is '''0.11'''.<br />
<br />
----<br />
<br />
===New Users===<br />
* [http://sourceforge.net/project/showfiles.php?group_id=143628 Download]<br />
* [[/Install|Installation Instructions]]<br />
* [[/FAQ|Frequently Asked Questions]]<br />
* [[/Supported_Devices|Supported Devices]]<br />
* [[/Changelog|Version History]]<br />
<br />
<br />
===Programmer Documentation===<br />
* [[/Build|Build Instructions]]<br />
* [[/Asm_Interface|Assembly language interface]]<br />
* [[/BASIC_Interface|BASIC language interface]]<br />
* [[/Sample_Code|Code Examples]]<br />
* [[/Error_Codes|Error codes]]<br />
<br />
[[Category:83Plus:Software|usb8x]]</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=83Plus:Software:usb8x/Install83Plus:Software:usb8x/Install2006-10-21T20:18:09Z<p>Dan Englender: </p>
<hr />
<div>usb8x is very easy to install. Basically just send it to your calculator. But, installation instructions are never complete without a numbered list, so here's how you install usb8x:<br />
# [http://sourceforge.net/projects/usb8x Download] usb8x from its sourceforge page.<br />
# If you want to build usb8x from source, read the [[../Build|build instructions]]. If you don't know what this means, skip this step.<br />
# Send the usb8x.8xk file to your TI-84 Plus calculator via TI-Connect or your favorite linking program.<br />
# Tada! usb8x is now installed. Since usb8x doesn't do anything by itself, you probably want to load some software that uses it, such as:<br />
## [[83Plus:Software:msd8x|msd8x]] - File browser for flash drives and hard drives.<br />
## [[83Plus:Software:USBTools|USBTools]] - Has demos for mice, keyboards, gamepads, hard drives, silverlink, and temperature sensor.</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=83Plus:Software:usb8x/Install83Plus:Software:usb8x/Install2006-10-21T20:16:33Z<p>Dan Englender: </p>
<hr />
<div>usb8x installation instructions:<br />
# [http://sourceforge.net/projects/usb8x Download] usb8x from its sourceforge page.<br />
# If you want to build usb8x from source, read the [[../Build|build instructions]]. If you don't know what this means, skip this step.<br />
# Send the usb8x.8xk file to your TI-84 Plus calculator via TI-Connect or your favorite linking program.<br />
# Tada! usb8x is now installed. Since usb8x doesn't do anything by itself, you probably want to load some software that uses it, such as:<br />
## [[83Plus:Software:msd8x|msd8x]] - File browser for flash drives and hard drives.<br />
## [[83Plus:Software:USBTools|USBTools]] - Has demos for mice, keyboards, gamepads, hard drives, silverlink, and temperature sensor.</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=83Plus:Software:usb8x/FAQ83Plus:Software:usb8x/FAQ2006-10-21T19:18:17Z<p>Dan Englender: 89t; link</p>
<hr />
<div>If you have a question not answered here, please feel free to ask it on the [[Talk:83Plus:Software:usb8x/FAQ|Discussion Page]].<br />
<br />
== General Questions ==<br />
=== With which calculators is usb8x compatible? ===<br />
usb8x is compatible with the TI-84 Plus and TI-84 Plus Silver Edition calculators. It appears to work best with calculators that have Boot Code 1.02. We're working on improving compatibility with Boot Code 1.00. '''usb8x is NOT compatible with the 89 Titanium'''.<br />
<br />
=== With which USB devices is usb8x compatible? ===<br />
Please check the [[../Supported Devices|Supported Devices]] page for details on device compatibility.<br />
<br />
=== How do I connect USB devices to my calculator? ===<br />
The TI-84 calculators have a mini-USB port. This means you can connect devices that have a mini-A plug, such as [http://www.vernier.com/easy/easytemp.html Vernier EasyTempâ„¢], directly. To connect devices with a standard A or B USB plug (i.e. almost all other USB peripherals), you need to buy an adapter. The [http://www.goldxproducts.com/showproduct.asp?pid=GXQU GoldX Quick Connect] adapter cable is available in many stores, and this [https://serialio.com//store/product_info.php?cPath=54_61&products_id=141 SERIALiO cable] will also work.<br />
<br />
=== How do I use usb8x? ===<br />
usb8x is a driver and doesn't let you "do" anything by itself. You need to download (or [[#Developer_Questions|create]]) a program that uses usb8x, such as [[83Plus:Software:msd8x|msd8x]] or [[83Plus:Software:USBTools|USBTools]].<br />
<br />
== Developer Questions ==<br />
=== How do I use usb8x from a BASIC program? ===<br />
usb8x can be accessed from BASIC via the OpenLib( and ExecLib commands. See the usb8x [[../BASIC_Interface|BASIC Documentation]] for more information.<br />
<br />
=== How do I use usb8x from an assembly program? ===<br />
usb8x can be accessed from RAM programs or applications via the U_CALL macro interface. See the usb8x [[../Asm_Interface|Assembly Documentation]] for more information.</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=83Plus:Software:Diffequ83Plus:Software:Diffequ2006-10-13T05:02:38Z<p>Dan Englender: </p>
<hr />
<div>Diffequ is a differential equation grapher for the TI-83/84 Plus developed by Martin Warmer, originally through the [http://code.google.com/soc/ 2006 Google Summer of Code]. <br />
<br />
Source code is available via its [https://svn.gravsys.com/soc/diffequ/ SVN repository].<br />
<br />
<br />
http://wikiti.denglend.net/stuff/diffeq.gif<br />
<br />
<br />
[[Category:83Plus:Software|Diffequ]]</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=83Plus:OS:84_Plus_USB_Information83Plus:OS:84 Plus USB Information2006-10-11T17:04:44Z<p>Dan Englender: /* Tested Devices */ removed list, linked to usb8x list</p>
<hr />
<div>:I moved this page from Talk:83Plus:BCALLs:5254 to here because it seems to fit better. Please note that this is still a work in progress, and don't take the information as gold. I figured having an option for a Talk page for this would outweigh the moving of it. For the time being, we'll leave the data formatted as-is, since it's still nicely done. --[[User:AndyJ|AndyJ]] 07:44, 27 May 2005 (PDT)<br />
<br />
<br />
<br />
OK, I've started this talk page to post information about the 84 Plus USB. This isn't the ideal place, since not all of this stuff has to do with entry point 5254, but it'll have to do. If anyone else would like to contribute any information or thoughts, please do so. Much of this data has been discovered by analyzing how the EasyData application interacts with the EasyTemp probe. --[[User:Dan Englender|Dan Englender]] 22:32, 23 May 2005 (PDT)<br />
<br />
Many thanks to Olivier Armand for providing information invaluable to figuring out some of the harder to decipher USB ports. --[[User:Dan Englender|Dan Englender]] 23:25, 9 Jul 2005 (PDT)<br />
<br />
== Easy Data ==<br />
The USB entry points that Easy Data uses are:<br />
5254<br />
5257<br />
525A<br />
525D<br />
5260<br />
<br />
These routines return carry flag with an error code in A on failure, or no carry on success. On success they return BC=(9C16), DE=(9C1A), and HL=(9C18). 9C16 = Vendor ID. 9C18 = Device ID. 9C1A = ????.<br />
<br />
<br />
The entry points seem to be called only on initialization and quit. On initialization 5254 then 525D are called, and then 525A six times. On quit, 5254, then 5260, then 5257 are called.<br />
<br />
=== 5254 BCALL ===<br />
The 5254 entry point seems to take a callback address to be passed in A (page) and HL (address). That callback address appears to be called on quit, after 5257 is called.<br />
<br />
=== 5260 and 5257 BCALLs ===<br />
The 5260 and 5257 entry points are called right after each other in the code, and don't seem to take any input. I guess they're some kind of USB shut down. 5260 doesn't do much of anything other than set 9C1E to 0000. 5257 plays with the ports some, and then clears the callback address. Since the call back address gets called, I'm assuming it must also call the callback address somewhere in there.<br />
<br />
=== 525A BCALL ===<br />
525A takes a pointer to a structure in HL. 9C1C will be set to the structure pointer. Some checks on port 4C and 8F are done at teh beginning of this call. A data segment of value: 21 09 0002 0000 0800 will be sent through the control data port. This cooresponds to Host to Device's endpoint, vendor type, set configuration.<br />
<br />
=== 525D BCALL ===<br />
525D takes a pointer to a structure in HL. The 525D entry point first checks to see if bit 3 of port 4C and bits 0 and 2 of port 8F are set. If they are not, it returns failure. These bits are not set by, say, plugging in the hardware. They are set, however, after 5254 has been called. After checking these bits, 9C1E is set to the passed structure pointer. If this value is zero, the routine will return failure. A value of 1 will be stored to HL+2, then a value of 1 will be output to port 8E, a value of 20h to port 94h, and success will be returned.<br />
<br />
=== 5290 BCALL ===<br />
A BCALL to 5290 alone is enough to turn on the LED on EasyTemp. (Though it turns on to a strange orange color which is never seen during EasyData execution). It must do some sort of USB initialization type stuff. If bit 3,(iy+41) is set, 5290 will fail. So this must either be a USB-already-initialized flag, or a Don't-Use-USB flag I guess.<br />
<br />
This BCALL appears to do the following:<br />
# Do stuff<br />
# Request the device descriptor with a maximum size of 8 bytes.<br />
# Issue a Set Address Request, with an address of 2<br />
# Request the device descriptor again, this time with a 18 byte maximum data size.<br />
# Check device description for an appropriate TI or Vernier device and quit if not found.<br />
# Do stuff<br />
<br />
Why are there two device descriptor requests? Presumably so that the calculator can check the peripheral's max packet size (which is in the first 8 bytes), so that it will know how to segmentize further traffic.<br />
<br />
=== 5293 BCALL ===<br />
This BCALL is enough to to turn the LED off on EasyTemp. It's called by 5260.<br />
<br />
=== Other ===<br />
<br />
The callback routine appears to recieve some kind of input in B. I'm not sure what yet.<br />
<br />
<br />
I'm, err, not exactly clear at this point how the app actually gets the temperature data from the EasyTemp probe, as the entry point seem to only be called on init and quit. The callback routine seemed a likely candidate, but it's not that either. Maybe there's something going on in the interrupt that I'm not aware of. Or maybe there are some more entry points used that I missed. ------- I'm now pretty sure that EasyData gets data through the 9C1E structure's callback which I believe returns data retrieved from an interrupt transfer in the OS's interrupt.<br />
<br />
<br />
EasyData is automatically started when you plug the EasyTemp into the USB port if: The current app is Home Screen, a program is not currently executing, and EasyTemp is loaded on the calculator. EasyTemp is searched for via the app header table below.<br />
<br />
==4087 Header==<br />
The calculator knows to run EasyData when the Probe is plugged in because it includes a special header at address 4087h.<br />
The format is as follows:<br />
<nowiki> db 096h, 0E2h, 00h, 01h<br />
dw TablePtr<br />
.....<br />
TablePtr:<br />
dw 1, TableEntryType, DataPtr<br />
.....<br />
DataPtr: ;This is the EasyData data<br />
db 03h, 80h, 03h, 00h, 0F7h, 08h, 02h, 00h<br />
db 80h, 03h, 00h, 0F7h, 08h, 03h, 00h<br />
db 80h, 03h, 00h, 0F7h, 08h, 04h, 00h<br />
db 00h, 00h</nowiki><br />
In theory, the Table should be terminated with a 0000 word. It does not appear that EasyData does this.<br />
<br />
=== Header Table Entries ===<br />
The TableEntryType value can be one of the follow:<br />
*1 - This type is checked for in what seems to be unused OS code. There's a string "IsDevice" that is used in conjunction with it. Perhaps it's an unimplemented feature, or perhaps it's debug code that's not active in the release OS. Your guess is as good as mine.<br />
*2 - This is for the library functions used by OpenLib and ExecLib<br />
*3 - This is for the USB auto-launch, as used by EasyData<br />
<br />
=== USB Data Table ===<br />
If the TableEntryType is 3, then the data will be USB data and will be formatted as follows: The first byte will be the number of entries in the USB data table. Then, each entry, starts with a byte. Not sure what that is. Then comes a word. Not really sure what that is either. But weird things happen if the high byte is not 00. And it appears that if the low byte is 01, only the vendor ID will be checked, if it's 03, the vendor ID and the product ID will be checked. If it's something else, well, something else happens. if the low byte was 03, then the next word will be the vendor ID, and the following word will be the product ID. If both of these match a connected USB device, then the app will launch.<br />
<br />
=== FindSpecialAppHeader BCALL ===<br />
The 50EF BCALL reads the 4087 Header. It is used by the OS. Returns SCF on failure, NC on success. On success, returns in HL the read table value. App name in OP1. Input DE is passed as the table entry to look for. Input A holds whether to look at certain app, or all apps. A = 0 means start at the first app, and search until you find an app with the appropriate header. A = 1 means start searching after the app in OP1. This would be used after the first success returned by A=0, to search the entire app list. A=2 means search only the app named in OP1.<br />
<br />
=== 5263 BCALL ===<br />
The 5263 BCALL reads the 4087 Header. it is used by the OS. This appears to be very similar to the above entry point, except that it searches all the pages by number, instead of searching by name. Input DE = header type to find. Output C on failure, NC on success. HL = table entry value. (appSearchPage) = page it was found on. This only finds the first instance of the header type.<br />
<br />
=== 5266 BCALL ===<br />
This allows you to continue a search you started with the 5263 BCALL. Input page in B.<br />
<br />
=== 5269 BCALL ===<br />
The 5269 BCALL is used by the OS after determining that an app with the USB special app header exists. In general, this entry point seems to compare the values in the USB app header data table with the values at 9C16, 9C18, and 9C1A. Some kind of ID I guess? In specific, it's actually very convoluted and strange code. Input is HL -> data table, A = page.<br />
<br />
== Hardware ==<br />
Ports 55h and 56h are initially polled in the interrupt routine to determine USB activity. If activity is detected, 4Dh, 82h, 84h, 86h, 8Fh, 91h, and others may be polled as well.<br />
<br />
=== Port 4C ===<br />
Some sort of status port. Values of 1A or 5A and 12 or 52 mean something. Default value is 22. Some of the host routines make sure bit 3 is set.<br />
<br />
=== Port 4D ===<br />
Some sort of status port. Bit 4 is set if a type A cable is plugged in. The high nibble appears to be A if nothing is plugged in, and 6 while connected to the computer. The port is checked bit-wise, but I haven't quite figured out how the rest of the bits function yet. I'm as yet unsure whether the values of this port are set based on external events alone, or also influenced by stuff going on in the interrupt. Will check with interrupts disabled later. There is a routine that is called when the bit 1 port 56 event occurs which first waits for bit 6,4D to be reset (which seems like the standard condition after a peripheral has been plugged in). It then does some outputs to ports 3A, 39, 4C, and 8F; after which it waits for bit 6,4D to be set (which seems like the standard condition after a peripheral has been initialized). This doesn't exactly clarify what bit 6 actually means though.<br />
<br />
=== Port 55 ===<br />
This port determines whether there's USB activity for the interrupt routine to take notice of. If any of the first five bits of the port are reset, that means something's happening in USB land. <br />
*bit 0 - Not sure. Only seems to happen with peripheral.<br />
*bit 1 - ???? (not checked by OS)<br />
*bit 2 - Check port 56 for details on what event has happened<br />
*bit 3 - ???? (not checked by OS)<br />
*bit 4 - Data waiting? Or read for data? Or something like this.<br />
<br />
=== Port 56 ===<br />
The default value for port 56h is 00. If bit 2 of port 55 is reset in the interrupt routine, this port should be checked to see what event occured. Each set bit indicates a particular event:<br />
* bit 0 - I've seen this bit set while playing around, but the OS doesn't use it.<br />
* bit 1 - Something to do with peripheral initialization?<br />
* bit 2 - ??<br />
* bit 3 - ??<br />
* bit 4 - Plug-in, A-cable<br />
* bit 5 - Unplug, A-cable<br />
* bit 6 - Plug-in, B-cable<br />
* bit 7 - Unplug, B-cable<br />
<br />
=== Port 5B ===<br />
I think if you load a value of 0 to this port, it will stop the USB controller from issuing interrupts to the calculator. Writing a value of 1 enables USB-related interrupts again.<br />
<br />
=== Port 80 ===<br />
This input/output port holds the address for the device. Valid both when acting as peripheral and when acting as host. (Though the OS always assigns address 2 when acting as host.)<br />
<br />
=== Port 82 ===<br />
Indicates outgoing data success. Seems to be valid both for data packets, and for IN/OUT tokens. Each bit indicates data sent successfully for that Ax port. It seems that the control port's bit registers for both incoming and outgoing data (instead of using port 84).<br />
<br />
=== Port 83 ===<br />
I'm guessing that this is a continuation of port 82, with each bit indicating outgoing data success for endpoint/pipes A8 through AF.<br />
<br />
=== Port 84 ===<br />
Indicates incoming data ready. Each bit indicates data ready to read on that Ax port. The control pipe acts as if it were an out pipe though, so don't expect to see bit 0 set. Check port 82 for control data.<br />
<br />
=== Port 85 ===<br />
I'm guessing that this is a continuation of port 84, with each bit indicating incoming data ready for endpoint/pipes A8 through AF.<br />
<br />
=== Port 86 ===<br />
Some sort of status port. Seems to generally hold a value of 0. Bits 5 or 7 being set seems to be an error condition. Other bits may or may not be error conditions, though it's beginning to look like they'll all errors or abort-conditions of some kind.<br />
<br />
=== Port 87 ===<br />
It's not clear to me what this port is, specifically. However, outputting a value of F7h appears to imply that calculator-as-peripheral has an address. FF has no address.<br />
<br />
=== Port 8C ===<br />
The low byte of the 15-bit frame counter. It is automatically incremented. I haven't timed it, but in theory it should be incremented about once per millisecond.<br />
<br />
=== Port 8D ===<br />
The high byte of the 15-bit frame counter. See port 8C.<br />
<br />
=== Port 8E ===<br />
This input/output port designates current endpoint to read from/transfer to. Can be 0-15.<br />
<br />
=== Port 8F ===<br />
Values of 1 or 3 are outputted to this port. I have no clue what they mean. After USB init, on read, it seems to be some sort of status. Bit 2 being set appears to imply calculator-as-host, reset seems to imply calculator-as-peripheral. Bit 3 set appears to mean B device, and reset means A device.<br />
<br />
=== Port 90 ===<br />
This port sets up the maximum packet size of outgoing pipes. See port 93.<br />
<br />
=== Port 91 ===<br />
This is the outgoing pipe command port. Port 82h seems to indicate when the command is ready. These bit values are valid in host mode on the control pipe, at least:<br />
* bit 1 - set indicates command in host to device direction, reset indicates from device to host<br />
* bit 3 - set means output data as SETUP packet/token?<br />
* bit 5 - set means output IN token? Reset means OUT token? (compliment of bit 1?)<br />
* bit 6 - reset means there is data associated with this command<br />
So commands for the control pipe would look like:<br />
*Send Control Command (no data)<br />
*# Output SETUP data to port A0<br />
*# Output 0A to port 91 (setup token/data from host to device)<br />
*# Output 60 to port 91 (go to status stage)<br />
*Send Control Command (with incoming data)<br />
*# Output SETUP data to port A0<br />
*# Output 0A to port 91 (setup token/data from host to device)<br />
*# Output 20 to port 91 (request IN data)<br />
*# Read data from port A0<br />
*# Output 42 to port 91 (go to status stage)<br />
*SendControl Command (with outgoing data)<br />
*# Output SETUP data to port A0<br />
*# Output 0A to port 91 (setup token/data from host to device)<br />
*# Output data to port A0<br />
*# Output 02 to port 91 (OUT data)<br />
*# Output 60 to port 91 (go to status stage)<br />
On read, bits 2 or 4 being set indicate an error state. Bit 2 is stall, bit 4 is NAK.<br />
<br />
=== Port 93 ===<br />
This port sets up the maximum packet size for incoming pipes. Multiply the value of the port by 8 to get the packet size. You should probably only set one bit. I have no clue what would happen if you set more than one.<br />
<br />
=== Port 94 ===<br />
This is the incoming pipe command port. Similar to port 91.<br />
<br />
=== Port 96 ===<br />
Holds the low byte of the size of the received and buffered input data for the currently selected endpoint/pipe. Read the data from the appropriate Ax port.<br />
<br />
=== Port 97 ===<br />
Presumably holds the high byte of the size of the received and buffered input data fro the currently selected endpoint/pipe. The 84P doesn't actually send any packets larger than 256 bytes, so it's not used.<br />
<br />
=== Port 98 ===<br />
If the description of port 9A is even remotely right, then this port has a good chance of being the same thing, but for outgoing pipes.<br />
<br />
=== Port 99 ===<br />
While I'm making things up, if ports 98, 9A, and 9B are all correct, then maybe this is the interrupt interval for setup of outgoing interrupt pipes and 9B is incoming interrupt pipes. *shrug*<br />
<br />
=== Port 9A ===<br />
OK, this is quite a strech, long shot, guess, etc; but here are some possibilities for this port: This might set up incoming pipes. The high nibble might define the type of pipe. 2 would be bulk, and 3 would be interrupt. That might make 1 isochronous, but I'm not going to go there. The low nibble might be which pipe to map the current endpoint to. This cooresponds to the port in the AX range. So 21 would map an incoming bulk pipe to port A1h. Or, that could all be completely nonsense. <br />
<br />
=== Port 9B ===<br />
This might setup the poll interval for an interrupt endpoint. Or it might not. Just a thought.<br />
<br />
=== Port A0 ===<br />
This is the control pipe data I/O port. I'm not sure if it's statically fixed this way, or if it is configured like the other pipes.<br />
<br />
=== Ports A1-A? ===<br />
Ports A1 and A2 are used by the OS as data I/O pipes and are set up via port 98 or 9A. It seems likely that more ports in the Ax range can be used as pipes, and I'm guessing all the ports A0-AF can be used.<br />
<br />
== RAM ==<br />
=== 9C13/9C14 ===<br />
9C13 is the page, and 9C14 is the address of a callback routine. It is set by the 5254 BCALL, and called at various times. I'm not really sure what the callback routine is for yet.<br />
<br />
=== 9C16 ===<br />
This is where the vendor ID is stored. It is populated by at least the 5290 BCALL, and perhaps others.<br />
<br />
=== 9C18 ===<br />
This is where the product ID is stored. It is populated by at least the 5290 BCALL, and perhaps others.<br />
<br />
=== 9C1A ===<br />
This is where the device release number is stored. It is populated by at least the 5290 BCALL, and perhaps others.<br />
<br />
=== 9C1C ===<br />
A pointer to another structure. Similar to 9C1E. Output control transfers?<br />
<br />
=== 9C1E ===<br />
A pointer to some sort of structure. First word of structure is a pointer to some sort of receive buffer. Reads from port A1 may be stored here. Perhaps for interrupt transfers? Offset 2 of structure is a byte value. Offset 3 of structure is a callback page and address<br />
<br />
=== 9C26 ===<br />
Byte value representing device state (calc as peripheral)<br />
*0 = Device in default state<br />
*1 = Device in addressed state<br />
*2 = Device in configured state<br />
<br />
=== 9C27 ===<br />
Another byte denoting something about the current state or operation. A value of 1 might imply a host->periph communication and a value of 2 might imply a periph->host communication.<br />
<br />
=== 9C28 ===<br />
Current USB status, or something like that.<br />
*1 = in the middle of USB host initialization<br />
*2 = Background intialization complete?<br />
*3 = Explicit (5290) initialization complete?<br />
*4 =????<br />
*5 = Something to do with uninit?<br />
*6 = Something to do with error states?<br />
<br />
=== 9C29 ===<br />
This is an 8 byte output buffer<br />
<br />
=== 9C31 ===<br />
This is an input buffer of undetermined length. Possibly 64 bytes.<br />
<br />
=== 9C75 ===<br />
A flag byte of some sort. Bits 5, 6, and 7 appear to be used. Bit 5 set means there's outgoing data in a control request (set report). Bit 5 reset means there's incoming data from a control request? Bit 6 reset might indicate that an 84P is connected as a peripheral, set might indicate a Vernier (or perhaps "other") peripheral. Bit seven set might indicate that a Set Address request was just received.<br />
<br />
=== 9C77 ===<br />
Used by the OS to hold the offset in the descriptor table of the descriptor to return.<br />
<br />
=== 9C78 ===<br />
Used by the OS to keep track of how many bytes it needs to send for USB device request replies.<br />
<br />
== Flags ==<br />
Flag byte 41 appears to be the main USB flag. Bit 0 of byte 43 is also used for something related.<br />
<br />
=== 2,(iy+40) ===<br />
If this flag is set, the 82/83 page set might be used for data storage when reading from port A2.<br />
<br />
=== 0,(iy+41) ===<br />
If this flag is set, it will cause a certain part of USB code to abort. This is the code that is called from the interrupt routine when port 55h is 0Fh, and port 56h is 00h. This flag is set in an odd piece of code that loops around an output to port 0A2h. It reads the data to output, however, from RAM pages 02h and 03h. Will have to look into in more detail later.<br />
<br />
=== 2,(iy+41) ===<br />
This flag is set after loading the values of 9C16, 9C18, and 9C1A. But then it's reset if the VID/PID is 0451, E00F. *shrug* In BCALL 5254, it is reset after the bcall to 5290. This bit is checked in Mon, I think.<br />
<br />
=== 3,(iy+41) ===<br />
If set, this means the viewscreen adaptor is connected via USB and has been initialized. If this is set the BCALL 5290 will immediately terminate. Set in Init if device is E00F. At end of init, if flag is set, screen will turn on and be refreshed.<br />
<br />
=== 5,(iy+41) ===<br />
Reset somewhere in USB code. Not sure what it is. This bit is checked in Mon, I think. I think this means there's bulk data to be read.<br />
<br />
=== 6,(iy+41) ===<br />
Reset somewhere in USB code. Not sure what it is.<br />
<br />
=== 7,(iy+41) ===<br />
Reset somewhere in USB code. Not sure what it is.<br />
<br />
== 84 as peripheral USB device requests ==<br />
This section describes the various USB commands that the calculator, acting as a peripheral, will accept. If the calculator receives commands that are not defined below, or if one of the checks designated as "makes sure" fails, it will set 9C84 to FF, and send a value of 60 out endpoint 0. NAK? Stall?<br />
<br />
=== Host to Device @ Device (0) ===<br />
These are commands in the host to device direction, with the device (as opposed to endpoint or interface) as the recipient.<br />
<br />
==== Clear Feature (1) ====<br />
When it receives a 0, 1 Clear Feature command, the calculator first makes sure that an address has been set (9C26 != 0). It also makes sure that the rest of the USB packet is not all zeros, for whatever reason. If processing is completed successfully, a value of 48 will be sent out port 91. WValues accepted as follows:<br />
*1 - According to the USB spec this is Device Remote Wakeup. Sets 9C76 to 0.<br />
*3 - Undefined according to USB spec, but this acts the same as 0,1,1 above.<br />
*5 - Undefined according to USB spec, this makes sure 9C74 is zero, sets 9C73 to zero, and 9C75 to 1.<br />
<br />
==== Set Feature (3) ====<br />
When it receives a 3 Set Feature command, the calculator checks that the rest of the packet is not all zeros. It accepts the following wValues:<br />
*1 - As per USB Spec, Sets Device Remote Wakeup. Sets 9C76 to 2<br />
*3 - Sets 9C73 to 1.<br />
*4 - Sets 9C74 to 1.<br />
*5 - Makes sure 9C74 is 0, and then sets 9C73 to 0 and 9C75 to 1.<br />
<br />
==== Set Address (5) ====<br />
Sets 9C86 to FF. Sets 9C71 to the received address value. (This will later be loaded to port 80). Sets bit 7 of 9C75 (which will indicate later to load the value to port 80). Outputs a value of 1 to port 5B. Outputs a value of 7F to port 87.<br />
<br />
==== Set Configuration (9) ====<br />
Makes sure the device is currently in the address or configured states. Accepts wValues as follows:<br />
* 0 - This will return the device to the address state. Sets 9C26 appropriatly and then outputs 1 to port 5B and FF to port 87.<br />
* 1 - Sets the calculator configuration 1, setting 9C26 appropriatly. Sets endpoint (8E) to 1, outputs 8 to port 90, 48 to port 91, 0 to port 92, 8 to port 93, 90 to port 94, and 0 to port 95. Then sets endpoint to 2, and repeats port outputs.<br />
<br />
=== Host to Device @ Endpoint (2) ===<br />
<br />
==== Clear Feature (1) ====<br />
Clear halt?<br />
<br />
==== Set Feature (3) ====<br />
Set halt?<br />
<br />
=== Device @ Device to Host (80) ===<br />
<br />
==== Get Status (0) ====<br />
Makes sure device is not in the default state. Makes sure packet data is not all zero (possibly with TIOS bug). Makes sure wLength is 2. If 9C76 is 2, responds with two bytes at offset of D5 from descriptor table. Otherwise responds with offset D6. The data seems to be 0,0 either way.<br />
<br />
==== Get Descriptor (6) ====<br />
Returns the requested descriptor. This is complicated. I'll fill in the details later.<br />
<br />
==== Get Configuration (8) ====<br />
Makes sure packet isn't all zeros. Makes sure wLength is 1. If currently in address state, returns 00. Otherwise returns 01.<br />
<br />
=== Device @ Interface to Host (81) ===<br />
<br />
==== Get Status (0) ====<br />
Makes sure the device is not in the default state. Makes sure packet is not all zeros. Makes sure wIndex is 0 and wLength is 2. Responds with 0,0.<br />
<br />
==== Get Interface(A) ====<br />
I'm pretty sure this code is buggy, as it make sure that the device is in the default state, when it ought to be in the configured state. Anyway, after making sure of that and making sure wIndex and wLength are 1, it returns 0.<br />
<br />
=== Device @ Endpoint to Host (82) ===<br />
<br />
==== Get Status (0) ====<br />
Details later...<br />
<br />
== In Other News ==<br />
<br />
=== Stuff ===<br />
* At some point, TI checks for USB devices VID: 045A, PID: E003, E008, and E00F. It seems to return "ok" on E008 and E003, and error on E00F. E008 is the 84P SE. E003 is the 84P. No clue what E00F is. Perhaps the Viewscreen connector?<br />
* I have successfully connected my calculator and digital camera, and retrieved the Product ID and Vendor ID from the camera. Yay :)<br />
* The EasyTemp is an HID device. Haven't figured out the protocol yet.<br />
* For the ever curious: if you have both the serial and USB links connected, the calculator will choose to use the USB link.<br />
* I don't know exactly how much current the calculator can provide, but it can definitely provide enough to power an optical mouse. I managed to turn the mouse on from the calculator, and everything seemed to work fine.<br />
<br />
=== Port Monitor ===<br />
I've written a [http://wikiti.denglend.net/stuff/portmon.8xk Port Monitor] that's been useful for figuring out what some of the ports do. It may be useful for others, but it's not extensively tested, so beware. "Setup Hook" records port data through the USB hook. "Setup Int" records data through an IM2 interrupt (will only take a new sample if a port in the requested range has changed). "Disable Mon" will Stop either the interrupt or hook monitor. "Exec Code" allows you to execute a BCALL or hex code, presumably while one of the monitors is running. Exec program isn't implemented yet. "View Data" allows you to view all the data by sample. "View Changes" allows you to view the data by port, only showing ports that had data changes. In future revisions I may add more monitor triggers through other hooks. Oh, it doesn't read from ports 82 or A0, as these will cause problems with USB activity. The interrupt doesn't read from ports 8C or 8D because these are just counter ports and throw off the sampling.<br />
<br />
=== Mouse ===<br />
So, I've successfully written an HID Mouse driver. One that, amazingly enough, actually works, with both corded and wireless optical mice. Video proof for disbelievers: [http://wikiti.denglend.net/stuff/mouse.avi mouse.avi (7MB)]. Source code will be going on SourceForge sometime in the near future.<br />
<br />
=== USB Protocol ===<br />
This PC<->calc (and presumably calc<->calc) USB protocol is vastly different than the serial protocol. A partial analysis of the protocol can be found [http://users.wpi.edu/~bmoody/usb.txt here].<br />
<br />
=== Presentation Link ===<br />
The presentation link, conjectured to be the E00F device (and E00E for the 89 version) appears to request 16 byte packets? If someone can get ahold of one of these to confirm that, it would be wonderful.<br />
<br />
=== Tested Devices ===<br />
For device compatibility see the [[83Plus:Software:usb8x/Supported_Devices|appropriate page]] in the usb8x documentation.<br />
<br />
=== Alpha version driver available ===<br />
I've released an alpha version of [[83Plus:Software:usb8x|usb8x]], the TI-84 Plus USB driver, on sourceforge. Check out the project's [http://usb8x.sourceforge.net webpage] for downloads and more information. This version provides a host driver-layer for other applications and programs to use, and drivers for USB mouse, USB keyboard, TI's silverlink graphlink, Vernier Easy/Go devices, HID gamepads, and mass storage devices. Keep in mind this is an ALPHA version, and many things will probably change before the final release. In other words, don't release any programs that rely on the current driver-layer.<br />
<br />
[[Category:83Plus:OS_Information|84 Plus USB Information]]</div>Dan Englenderhttps://wikiti.brandonw.net/index.php?title=83Plus:Software:usb8x/Supported_Devices83Plus:Software:usb8x/Supported Devices2006-10-11T17:03:16Z<p>Dan Englender: Easytemp driver exists now</p>
<hr />
<div>Most USB devices that are self-powered, or draw 100mA or less current from the USB bus should be compatible with usb8x. Below is a list of device classes and specific devices that have been tested. Devices that require isochronous endpoints or have an integrated USB hub are not currently compatible.<br />
<br />
== Internal Driver ==<br />
These devices work and usb8x contains an internal driver to control them.<br />
* HID Keyboard<br />
* HID Mouse<br />
* Mass Storage Device. Tested with:<br />
** Sandisk Cruzer<br />
** Lexar JumpDrive/Secure<br />
** SMI Corp USB Disk<br />
** 512 Mini Disk Genie<br />
* TI Silverlink<br />
* Some gamepad controllers. Tested with:<br />
** Logitech Precision Gamepad<br />
** [http://www.retrousb.com/nintendo.html RetroZone NES pad]<br />
** [http://www.planetgamecube.com/hardArt.cfm?artid=2459 Skillz Gamecube to USB] (The company no longer seems to exist.)<br />
* Vernier EasyTemp<br />
<br />
== External Driver ==<br />
These devices work and an external driver exists to control them.<br />
* None<br />
<br />
== Works, No Complete Driver ==<br />
These devices have been tested to work with usb8x, but no complete driver currently exists.<br />
* EMS HID Playstation 2 controller adapter<br />
* HID Mouse/Keyboard Combo (I ([[User:84plusfreak|84plusfreak]]) am writing a driver for it.)<br />
<br />
== Should Work ==<br />
These devices have been tested to properly initialize with usb8x, but no drivers have been attempted.<br />
* Canon i850 printer<br />
* Canon SD400 digital camera<br />
* Motorola SURFboard cable modem<br />
* Motorola V220 (can act as USB Modem)<br />
* TI-84 Plus (calc<->calc)<br />
<br />
== Not Compatible ==<br />
These devices are not compatible with usb8x.<br />
* Ezonics webcam - isochronous endpoints<br />
* Netgear WG111 802.11 adapter - draws too much current?<br />
* SMC 802.11b adapter - draws too much current<br />
* Taurus MBT-1203 bluetooth adapter - has integrated hub</div>Dan Englender