Difference between revisions of "83Plus:Software:usb8x/Sample Code"

From WikiTI
Jump to: navigation, search
(Added keyboard detect)
(I have fixed the links on this page and hid the comments. This is the worst page I have seen so far. I have no idea what the author was trying to do with the code, but it needs to be fixed.)
 
(19 intermediate revisions by 2 users not shown)
Line 2: Line 2:
 
== BASIC ==
 
== BASIC ==
 
=== Mouse Demo ===
 
=== Mouse Demo ===
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 the mouse cursor.
+
This example uses the [[83Plus:Software:usb8x/BASIC_Interface/MouseInit|MouseInit]], [[83Plus:Software:usb8x/BASIC_Interface/MouseDo|MouseDo]], and [[83Plus:Software:usb8x/BASIC_Interface/KillUSB|KillUSB]] entry points to control a point on the screen with a USB mouse.
 
  <nowiki>OpenLib(USBDRV8X
 
  <nowiki>OpenLib(USBDRV8X
 
{2                  ;MouseInit
 
{2                  ;MouseInit
Line 8: Line 8:
 
If Ans(1            ;If MouseInit returns error,
 
If Ans(1            ;If MouseInit returns error,
 
Return              ; then quit
 
Return              ; then quit
-968->Xmin
+
-1452->Xmin
968->Xmax
+
1452->Xmax
-640->Ymin
+
-960->Ymin
640->Ymax
+
960->Ymax
 
0->X
 
0->X
 
0->Y
 
0->Y
Line 32: Line 32:
 
{1                  ;KillUSB
 
{1                  ;KillUSB
 
ExecLib</nowiki>
 
ExecLib</nowiki>
 +
 +
=== Keyboard demo ===
 +
==== Simple Example ====
 +
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.
 +
 +
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.
 +
:
 +
:OpenLib(USBDRV8X
 +
:{10
 +
:ExecLib
 +
:{40,0,12,153,120,0,132}&rarr;<span style="font-variant: small-caps; font-size: 65%;">L</span>BLANK
 +
:
 +
:While 1
 +
:{40,0,12,153,120,0,132}
 +
:While prod(Ans=<span style="font-variant: small-caps; font-size: 65%;">L</span>BLANK)=1
 +
:If getKey&ne;0
 +
:Goto SP
 +
:{11
 +
:ExecLib
 +
:End
 +
:
 +
:Ans(3&rarr;A
 +
:<span style="font-variant: small-caps; font-size: 65%;">L</span>KBDSC(A)&rarr;B
 +
: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
 +
:
 +
:End
 +
:
 +
:Lbl SP
 +
:{1
 +
:ExecLib
 +
:
 +
:Stop
 +
<!--Change the first line to "Goto D" and run this program once to get all of this information updated.-->
 +
:Lbl D
 +
:{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,
 +
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
 +
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
 +
,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
 +
:{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
 +
,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
 +
,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
 +
:{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
 +
2,61,73,78,83,88,93,96,97,98,99,100,101,102,103,104,105,106,107,108,114,118,125,
 +
130,135,140,141,142,143,144,145,146,147,148,149,150,151,156,162,165,174,179,184,
 +
189,194,195,196,197,198,199,200,201,202,203,204,206,211,216,221,226,239,243,247,
 +
252,257,262,271,275,279}&rarr;<span style="font-variant: small-caps; font-size: 65%;">L</span>KBLOC
 +
:"ESCF1F2F3F4F5F6F7F8F9F10F11F12Tilde1234567890-=SlshBackspacePrint ScreenPauseN
 +
UM /NUM *NUM -TABQWERTYUIOP[]InsertHomePage UpNUM 7NUM 8NUM 9ASDFGHJKL:'EnterDel
 +
eteEndPage DownNUM 4NUM 5NUM 6NUM +ZXCVBNM,./UpNUM 1NUM 2NUM 3Space<Right Click>
 +
LeftDownRightNUM 0NUM .NUM Enter<01><02><03>"&rarr;Str2
 +
 +
==== More Useful Example ====
 +
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.
 +
<!--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.-->
 +
<!--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.-->
 +
:"abcdefghijklmnopqrstuvwxyz1234567890-=[]',./ ABCDEFGHIJKLMNOPQ
 +
RSTUVWXYZ~!^*()+_{} :<sup>&minus;</sup>&lt;&gt;? "&rarr;Str2
 +
:{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,
 +
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
 +
,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
 +
,0}&rarr;<span style="font-variant: small-caps; font-size: 65%;">L</span>KBSCL
 +
:OpenLib(USBDRV8X
 +
:{10
 +
:ExecLib
 +
:{40,0,12,153,120,0,132}&rarr;<span style="font-variant: small-caps; font-size: 65%;">L</span>BLANK
 +
:"&pi;&rarr;Str1
 +
:While 1
 +
:{40,0,12,153,120,0,132}
 +
:While prod(Ans=<span style="font-variant: small-caps; font-size: 65%;">L</span>BLANK)=1
 +
:If getKey&ne;0
 +
:Goto SP
 +
:{11
 +
:ExecLib
 +
:End
 +
:Ans&rarr;<span style="font-variant: small-caps; font-size: 65%;">L</span>TEMP
 +
:<span style="font-variant: small-caps; font-size: 65%;">L</span>TEMP(3&rarr;A
 +
:If A=42 and length(Str1)>1
 +
:Then
 +
:sub(Str1,1,length(Str1)-1&rarr;Str1
 +
:ClrHome
 +
:Output(1,1,Str1
 +
:End
 +
:If A=40
 +
:Goto E
 +
:If <span style="font-variant: small-caps; font-size: 65%;">L</span>KBSCL(A)=0
 +
:End
 +
:
 +
:
 +
:
 +
:<span style="font-variant: small-caps; font-size: 65%;">L</span>TEMP(2&rarr;S
 +
:0&rarr;T
 +
:S+(S-128<u>&gt;</u>0)(<sup>&minus;</sup>128&rarr;S
 +
:S+(S-64<u>&gt;</u>0)(<sup>&minus;</sup>64&rarr;S
 +
:If S-32<u>&gt;</u>0
 +
:Then
 +
:1&rarr;T
 +
:S-32&rarr;S
 +
:End
 +
:S+(S-16<u>&gt;</u>0)(<sup>&minus;</sup>16&rarr;S
 +
:S+(S-8<u>&gt;</u>0)(<sup>&minus;</sup>8&rarr;S
 +
:S+(S-4<u>&gt;</u>0)(<sup>&minus;</sup>4&rarr;S
 +
:If S-2<u>&gt;</u>0
 +
:Then
 +
:1&rarr;T
 +
:S-2&rarr;S
 +
:End
 +
:Str1+sub(Str2,<span style="font-variant: small-caps; font-size: 65%;">L</span>KBSCL(A)+(T=1)48,1&rarr;Str1
 +
:If length(Str1)=2 and sub(Str1,1,1)="&pi;
 +
:sub(Str1,2,1&rarr;Str1
 +
:Output(1,1,Str1
 +
:End
 +
:Lbl E
 +
:Lbl SP
 +
:{1
 +
:ExecLib
 +
:DelVar <span style="font-variant: small-caps; font-size: 65%;">L</span>TEMP
 +
:DelVar <span style="font-variant: small-caps; font-size: 65%;">L</span>MODS
  
 
== Assembly (TASM) ==
 
== Assembly (TASM) ==
Code for TASM-compatible assemblers.  Use usb8xtsm.inc instead of usb8x.inc.  TASM itself is apparently incompatible with usb8x macros, but Brass and SPASM work correctly.
+
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]. 
 
=== Mouse Demo ===
 
=== Mouse Demo ===
This code uses [[../Asm_Interface/DriverInit|DriverInit]], [[../Asm_Interface/MouseInit|MouseInit]], [[../Asm_Interface/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.
+
This code uses [[83Plus:Software:usb8x/Asm_Interface/DriverInit|DriverInit]], [[83Plus:Software:usb8x/Asm_Interface/Mouse/MouseInit|MouseInit]], [[83Plus:Software:usb8x/Asm_Interface/Mouse/MouseGetKey|MouseGetKey]], [[83Plus:Software:usb8x/Asm_Interface/HostKill|HostKill]], and [[83Plus:Software:usb8x/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.
  <nowiki> U_CALL_INIT(Stub) ;Initialize U_CALL system
+
 
jp c,error
+
 
ld hl,USBDriverBuf
+
{| border="0" cellpadding="0"  cellspacing="0"
         U_CALL(uDriverInit) ;Initialize Driver
+
|-
jp c,error
+
||
ld hl,DBuf
+
||'''<center>Brass</center>'''
ld bc,256
+
||'''<center>ZDS</center>'''
bcall(_MemClear) ;Clear descriptor buffer
+
|-
ld hl,DBuf
+
||
ld b,0 ;allow diagonal keys
+
  <nowiki>
U_CALL(uMouseInit) ;Initialize Mouse
+
jp c,error
+
bcall(_GrBufClr)
+
xor a
+
          
ld (MouseBtn),a
+
ld a,50*2
+
ld (MouseX),a
+
ld a,32*2
+
ld (MouseY),a
+
call DispCursor ;Display mouse cursor
+
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 
MainLoop:
 
MainLoop:
bcall(_GrBufCpy)
+
bcall(_GetCSC)
+
cp skClear
+
jr z,MouseDone
+
call DispCursor ;Erase cursor
+
ld b,4 ;Buffer to screen copy is kind of slow, so let's
+
gkloop: ; update the cursor a few times for each buffer copy
+
gkloop:
push bc
+
U_CALL(uMouseGetKey) ;Get mouse info from usb8x
+
call MouseUpdateCursor ;Update cursor position
+
pop bc
+
djnz gkloop
+
call DispCursor ;Re-display cursor
+
jr MainLoop
+
  
 
MouseDone:
 
MouseDone:
U_CALL(uHostKill) ;Disconnect power from mouse
+
U_CALL(uDriverKill) ;Kill driver
+
ret
+
</nowiki>
 +
||
 +
<nowiki>
 +
U_CALL_INIT(Stub)
 +
jp c,error
 +
ld hl,USBDriverBuf
 +
U_CALL(DriverInit)
 +
jp c,error
 +
ld hl,DBuf
 +
ld bc,256
 +
bcall(_MemClear)
 +
ld de,DBuf
 +
ld b,0
 +
U_CALL(MouseInit)
 +
jp c,error
 +
bcall(_GrBufClr)
 +
xor a
 +
ld (MouseBtn),a
 +
ld a,50*2
 +
ld (MouseX),a
 +
ld a,32*2
 +
ld (MouseY),a
 +
call DispCursor
 +
 
 +
bcall(_GrBufCpy)
 +
bcall(_GetCSC)
 +
cp skClear
 +
jr z,MouseDone
 +
call DispCursor
 +
ld b,4
 +
 
 +
push bc
 +
U_CALL(MouseGetKey)
 +
call MouseUpdateCursor
 +
pop bc
 +
djnz gkloop
 +
call DispCursor
 +
jr MainLoop
 +
 
 +
 
 +
U_CALL(HostKill)
 +
U_CALL(DriverKill)
 +
ret</nowiki>
 +
||
 +
 
 +
<nowiki>
 +
U_CALL_INIT Stub
 +
jp c,error
 +
ld hl,USBDriverBuf
 +
U_CALL  DriverInit
 +
jp c,error
 +
ld hl,DBuf
 +
ld bc,256
 +
B_CALL  MemClear
 +
ld de,DBuf
 +
ld b,0
 +
U_CALL  MouseInit
 +
jp c,error
 +
B_CALL  GrBufClr
 +
xor a
 +
ld (MouseBtn),a
 +
ld a,50*2
 +
ld (MouseX),a
 +
ld a,32*2
 +
ld (MouseY),a
 +
call DispCursor
 +
 
 +
B_CALL  GrBufCpy
 +
B_CALL  GetCSC
 +
cp skClear
 +
jr z,MouseDone
 +
call DispCursor
 +
ld b,4
 +
 
 +
push bc
 +
U_CALL  MouseGetKey
 +
call MouseUpdateCursor
 +
pop bc
 +
djnz gkloop
 +
call DispCursor
 +
jr MainLoop
 +
 
 +
 
 +
U_CALL  HostKill
 +
U_CALL  DriverKill
 +
ret</nowiki>
 +
 
 +
||
 +
<nowiki>
 +
;Initialize U_CALL system
 +
 
 +
 
 +
;Initialize usb8x driver
 +
 
 +
 
 +
 
 +
;Clear descriptor buffer
 +
 
 +
;allow diagonal keys
 +
;Initialize mouse driver
 +
 
 +
 
 +
 
 +
 
 +
 
 +
 
 +
 
 +
 
 +
;Display mouse cursor
 +
 
 +
 
 +
 
 +
 
 +
 
 +
;Erase cursor
 +
;Buffer copy is slow, so
 +
; update cursor a few times
 +
 
 +
;Get mouse info from usb8x
 +
;Update cursor position
 +
 
 +
 
 +
;Re-display cursor
 +
 
 +
 
 +
 
 +
;Disconnect power from mouse
 +
;Kill driver
 
</nowiki>
 
</nowiki>
 +
 +
|}
  
 
== Assembly (ZDS) ==
 
== Assembly (ZDS) ==
 
Code for ZDS compatible assemblers.  usb8x is designed to be used with a ZDS-compatible assembler.
 
Code for ZDS compatible assemblers.  usb8x is designed to be used with a ZDS-compatible assembler.
 +
 +
=== FindPipe ===
 +
This code segment, taken from the mass storage driver, illustrates the use of [[83Plus:Software:usb8x/Asm_Interface/FindPipe|FindPipe]] to get the address of an endpoint matching certain characteristics.
 +
<nowiki>      ld    b,pipeBulk
 +
      ld    c,pipeOut
 +
      ld    hl,DescBuf
 +
      U_CALL FindPipe              ;Find an outgoing bulk endpoint
 +
      jr    c,error
 +
      ld    a,b
 +
      ld    (OutPipe),a            ;Store the endpoint address for later use
 +
 +
      ld    b,pipeBulk
 +
      ld    c,pipeIn
 +
      ld    hl,DescBuf
 +
      U_CALL FindPipe              ;Find an incoming bulk endpoint
 +
      jr    c,error
 +
      ld    a,b
 +
      ld    (InPipe),a</nowiki>
  
 
=== Keyboard Detect ===
 
=== Keyboard Detect ===
This code illustrates the use of [[../Asm_Interface/AutoSetup|AutoSetup]] and [[../Asm_Interface/GetClass|GetClass]] to determine if the attached device is a keyboard.
+
This code illustrates the use of [[83Plus:Software:usb8x/Asm_Interface/AutoSetup|AutoSetup]] and [[83Plus:Software:usb8x/Asm_Interface/GetClass|GetClass]] to determine if the attached device is a keyboard.
  <nowiki>      U_CALL_INIT KBDCallBack    ;Inialize U_CALL and Callback RAM calls
+
  <nowiki>      U_CALL_INIT KBDCallBack    ;Initialize U_CALL and Callback RAM calls
 
       jr    c,NoUSBDriver        ;If it returns C, that means USB8X isn't loaded on calc
 
       jr    c,NoUSBDriver        ;If it returns C, that means USB8X isn't loaded on calc
 
       ld    hl,USBDriverBuf
 
       ld    hl,USBDriverBuf
Line 90: Line 364:
 
       ld    hl,DescBuf
 
       ld    hl,DescBuf
 
       U_CALL AutoSetup            ;Initialize and configure USB device
 
       U_CALL AutoSetup            ;Initialize and configure USB device
       jp     c,USBError
+
       jr     c,USBError
  
 
       ld    hl,DescBuf
 
       ld    hl,DescBuf
 
       U_CALL GetClass            ;Get the class information for the attached device
 
       U_CALL GetClass            ;Get the class information for the attached device
       jp     c,USBError
+
       jr     c,USBError
       cp    3                    ;Keyboards class = 3
+
       cp    3                    ;Keyboard class = 3
       jp     nz,NotKBD
+
       jr     nz,NotKBD
 
       dec    b                    ;subclass = 1
 
       dec    b                    ;subclass = 1
       jp     nz,NotKBD
+
       jr     nz,NotKBD
 
       dec    c                    ;protocol = 1
 
       dec    c                    ;protocol = 1
       jp     nz,NotKBD
+
       jr     nz,NotKBD
 
;Keyboard is attached.  Code would continue here.   
 
;Keyboard is attached.  Code would continue here.   
 
;Typically at this point you would call ReqData to start reading data from the keyboard</nowiki>
 
;Typically at this point you would call ReqData to start reading data from the keyboard</nowiki>

Latest revision as of 08:26, 10 November 2009

Example code using the usb8x assembly and BASIC interfaces

BASIC

Mouse Demo

This example uses the MouseInit, MouseDo, and KillUSB entry points to control a point on the screen with a USB mouse.

OpenLib(USBDRV8X
{2                  ;MouseInit
ExecLib
If Ans(1            ;If MouseInit returns error,
Return              ; then quit
-1452->Xmin
1452->Xmax
-960->Ymin
960->Ymax
0->X
0->Y
Repeat getKey
{3                  ;MouseDo
ExecLib
Ans->L1
If L1(1             ;If MouseDo returns error,
Goto 1              ; restart loop
If 127<L1(3         ;If x direction is left,
L1(3)-256->L1(3     ; change to negative #
If 127<L1(4         ;If y direction is up,
L1(4)-256->L1(4     ; change to negative #
Pt-Off(X,Y
X+L1(3->X
Y-L1(4->Y
Pt-On(X,Y
Lbl 1
End
{1                  ;KillUSB
ExecLib

Keyboard demo

Simple Example

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.

The requirement of LKBDSC 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.

:
:OpenLib(USBDRV8X
:{10
:ExecLib 
:{40,0,12,153,120,0,132}→LBLANK
:
:While 1
:{40,0,12,153,120,0,132}
:While prod(Ans=LBLANK)=1
:If getKey≠0
:Goto SP
:{11
:ExecLib 
:End
:
:Ans(3→A
:LKBDSC(A)→B
:Disp sub(Str2,LKBLOC(B),LKBLEN(B
:
:End
:
:Lbl SP
:{1
:ExecLib 
:
:Stop
:Lbl D
:{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,
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
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
,32,33,71,93,83,84,85,68,69,70,50,51,52,91,92,0,87}→LKBDSC
:{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
,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
,1,1,2,5,5,5,5,13,4,4,5,5,5,9,4,4,4}→LKBLEN
:{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
2,61,73,78,83,88,93,96,97,98,99,100,101,102,103,104,105,106,107,108,114,118,125,
130,135,140,141,142,143,144,145,146,147,148,149,150,151,156,162,165,174,179,184,
189,194,195,196,197,198,199,200,201,202,203,204,206,211,216,221,226,239,243,247,
252,257,262,271,275,279}→LKBLOC
:"ESCF1F2F3F4F5F6F7F8F9F10F11F12Tilde1234567890-=SlshBackspacePrint ScreenPauseN
UM /NUM *NUM -TABQWERTYUIOP[]InsertHomePage UpNUM 7NUM 8NUM 9ASDFGHJKL:'EnterDel
eteEndPage DownNUM 4NUM 5NUM 6NUM +ZXCVBNM,./UpNUM 1NUM 2NUM 3Space<Right Click>
LeftDownRightNUM 0NUM .NUM Enter<01><02><03>"→Str2

More Useful Example

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.

:"abcdefghijklmnopqrstuvwxyz1234567890-=[]',./ ABCDEFGHIJKLMNOPQ
RSTUVWXYZ~!^*()+_{} :<>? "→Str2
:{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,
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
,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
,0}→LKBSCL
:OpenLib(USBDRV8X
:{10
:ExecLib
:{40,0,12,153,120,0,132}→LBLANK
:"π→Str1
:While 1
:{40,0,12,153,120,0,132}
:While prod(Ans=LBLANK)=1
:If getKey≠0
:Goto SP
:{11
:ExecLib 
:End
:Ans→LTEMP
:LTEMP(3→A
:If A=42 and length(Str1)>1
:Then
:sub(Str1,1,length(Str1)-1→Str1
:ClrHome
:Output(1,1,Str1
:End
:If A=40
:Goto E
:If LKBSCL(A)=0
:End
:
:
:
:LTEMP(2→S
:0→T
:S+(S-128>0)(128→S
:S+(S-64>0)(64→S
:If S-32>0
:Then
:1→T
:S-32→S
:End
:S+(S-16>0)(16→S
:S+(S-8>0)(8→S
:S+(S-4>0)(4→S
:If S-2>0
:Then
:1→T
:S-2→S
:End
:Str1+sub(Str2,LKBSCL(A)+(T=1)48,1→Str1
:If length(Str1)=2 and sub(Str1,1,1)="π
:sub(Str1,2,1→Str1
:Output(1,1,Str1
:End
:Lbl E
:Lbl SP
:{1
:ExecLib
:DelVar LTEMP
:DelVar LMODS

Assembly (TASM)

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 Brass. Use usb8xtsm.inc instead of usb8x.inc.

Mouse Demo

This code uses DriverInit, MouseInit, MouseGetKey, HostKill, and 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.


Brass
ZDS
	
	
	
        
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
MainLoop:
	
	
	
	
	
	 
gkloop:	
	
	
	
	
	
	
	

MouseDone:
	
	
	
U_CALL_INIT(Stub)
jp	c,error
ld	hl,USBDriverBuf
U_CALL(DriverInit)
jp	c,error
ld	hl,DBuf
ld	bc,256
bcall(_MemClear)
ld	de,DBuf
ld	b,0
U_CALL(MouseInit)
jp	c,error
bcall(_GrBufClr)
xor	a
ld	(MouseBtn),a
ld	a,50*2
ld	(MouseX),a
ld	a,32*2
ld	(MouseY),a
call	DispCursor

bcall(_GrBufCpy)
bcall(_GetCSC)
cp	skClear
jr	z,MouseDone
call	DispCursor
ld	b,4

push	bc
U_CALL(MouseGetKey)
call	MouseUpdateCursor
pop	bc
djnz	gkloop
call	DispCursor
jr	MainLoop


U_CALL(HostKill)
U_CALL(DriverKill)
ret
U_CALL_INIT Stub
jp	c,error
ld	hl,USBDriverBuf
U_CALL  DriverInit
jp	c,error
ld	hl,DBuf
ld	bc,256
B_CALL  MemClear
ld	de,DBuf
ld	b,0
U_CALL  MouseInit
jp	c,error
B_CALL  GrBufClr
xor	a
ld	(MouseBtn),a
ld	a,50*2
ld	(MouseX),a
ld	a,32*2
ld	(MouseY),a
call	DispCursor

B_CALL  GrBufCpy
B_CALL  GetCSC
cp	skClear
jr	z,MouseDone
call	DispCursor
ld	b,4

push	bc
U_CALL  MouseGetKey
call	MouseUpdateCursor
pop	bc
djnz	gkloop
call	DispCursor
jr	MainLoop


U_CALL  HostKill
U_CALL  DriverKill
ret
;Initialize U_CALL system


;Initialize usb8x driver



;Clear descriptor buffer

;allow diagonal keys
;Initialize mouse driver








;Display mouse cursor





;Erase cursor
;Buffer copy is slow, so 
; update cursor a few times 

;Get mouse info from usb8x
;Update cursor position


;Re-display cursor



;Disconnect power from mouse
;Kill driver

Assembly (ZDS)

Code for ZDS compatible assemblers. usb8x is designed to be used with a ZDS-compatible assembler.

FindPipe

This code segment, taken from the mass storage driver, illustrates the use of FindPipe to get the address of an endpoint matching certain characteristics.

       ld     b,pipeBulk
       ld     c,pipeOut
       ld     hl,DescBuf
       U_CALL FindPipe               ;Find an outgoing bulk endpoint
       jr     c,error
       ld     a,b
       ld    (OutPipe),a             ;Store the endpoint address for later use

       ld     b,pipeBulk
       ld     c,pipeIn
       ld     hl,DescBuf
       U_CALL FindPipe               ;Find an incoming bulk endpoint
       jr     c,error
       ld     a,b
       ld     (InPipe),a

Keyboard Detect

This code illustrates the use of AutoSetup and GetClass to determine if the attached device is a keyboard.

       U_CALL_INIT KBDCallBack     ;Initialize U_CALL and Callback RAM calls
       jr     c,NoUSBDriver        ;If it returns C, that means USB8X isn't loaded on calc
       ld     hl,USBDriverBuf
       U_CALL DriverInit           ;Initialize USB driver
       ld     hl,DescBuf
       U_CALL AutoSetup            ;Initialize and configure USB device
       jr     c,USBError

       ld     hl,DescBuf
       U_CALL GetClass             ;Get the class information for the attached device
       jr     c,USBError
       cp     3                    ;Keyboard class = 3
       jr     nz,NotKBD
       dec    b                    ;subclass = 1
       jr     nz,NotKBD
       dec    c                    ;protocol = 1
       jr     nz,NotKBD
;Keyboard is attached.  Code would continue here.  
;Typically at this point you would call ReqData to start reading data from the keyboard