A51 MACRO ASSEMBLER RBDC 25/07/99 15:58:57 PAGE 1 DOS MACRO ASSEMBLER A51 V5.28m OBJECT MODULE PLACED IN RBDC.OBJ ASSEMBLER INVOKED BY: C:\ANCHOR\KEIL2K\BIN\A51.EXE RBDC.A51 RB(0) DB EP LOC OBJ LINE SOURCE 1 NAME ReaderBoardwithDualConfigurations 2 3 $INCLUDE(../Declare.A51) =1 4 ; This module declares the variables and constants used in the examples =1 5 ; It is common to all of the examples =1 6 ; =1 7 ; Declare Special Function Registers used 00A8 =1 8 EI DATA 0A8H 00E8 =1 9 EIE DATA 0E8H ; EZ-USB specific 0091 =1 10 EXIF DATA 091H ; EZ-USB specific 00D8 =1 11 EICON DATA 0D8H ; EZ-USB specific 0092 =1 12 PageReg DATA 092H ; EZ-USB specific, used with MOVX @Ri 0086 =1 13 DPS DATA 086H ; EZ-USB specific, used with dual data pointers =1 14 ; =1 15 ; "External" memory locations used, EZ-USB specific =1 16 ; Note that most of these variables are in Page 7FH 7FE8 =1 17 SETUPDAT EQU 07FE8H 7FD4 =1 18 SUDPTR EQU 07FD4H 7FB4 =1 19 EP0Control EQU 07FB4H 7F00 =1 20 EP0InBuffer EQU 07F00H 7EC0 =1 21 EP0OutBuffer EQU 07EC0H ; Not in Page 7FH 7E80 =1 22 EP1InBuffer EQU 07E80H ; Not in Page 7FH 7FB5 =1 23 IN0ByteCount EQU 07FB5H 7FC5 =1 24 Out0ByteCount EQU 07FC5H 7FB7 =1 25 IN1ByteCount EQU 07FB7H 7FAC =1 26 IN07IEN EQU 07FACH 7FA9 =1 27 IN07IRQ EQU 07FA9H 7FAD =1 28 OUT07IEN EQU 07FADH 7FAA =1 29 OUT07IRQ EQU 07FAAH 7FAE =1 30 USBIEN EQU 07FAEH 7FAB =1 31 USBIRQ EQU 07FABH 7FD6 =1 32 USBControl EQU 07FD6H 7FA6 =1 33 I2CData EQU 07FA6H 7FA5 =1 34 I2CControl EQU 07FA5H 7F93 =1 35 PortA_Config EQU 07F93H 7F94 =1 36 PortB_Config EQU 07F94H 7F95 =1 37 PortC_Config EQU 07F95H 7F96 =1 38 PortA_OUT EQU 07F96H 7F97 =1 39 PortB_OUT EQU 07F97H 7F98 =1 40 PortC_OUT EQU 07F98H 7F99 =1 41 PortA_PINS EQU 07F99H 7F9A =1 42 PortB_PINS EQU 07F9AH 7F9B =1 43 PortC_PINS EQU 07F9BH 7F9C =1 44 PortA_OE EQU 07F9CH 7F9D =1 45 PortB_OE EQU 07F9DH 7F9E =1 46 PortC_OE EQU 07F9EH =1 47 ; =1 48 ; Byte Variables =1 49 ---- =1 50 DSEG AT 20H 0020 =1 51 FLAGS: DS 1 ; This register is bit-addressable =1 52 ; Bit Variables 0000 =1 53 Configured EQU FLAGS.0 ; Is this device configured 0001 =1 54 STALL EQU FLAGS.1 ; Need to STALL endpoint 0 0002 =1 55 SendData EQU FLAGS.2 ; Need to send data to PC Host 0003 =1 56 IsDescriptor EQU FLAGS.3 ; Enable a shortcut reply =1 57 ; 0021 =1 58 MonitorSpace: DS 1FH ; Used by Dscope A51 MACRO ASSEMBLER RBDC 25/07/99 15:58:57 PAGE 2 0040 =1 59 Temp: DS 1 ; A temporary working register 0041 =1 60 Idle_Time: DS 1 ; The time the PC host wants us to wait 0042 =1 61 Expired_Time: DS 1 ; A downcounter for timed Reports 0043 =1 62 ReplyBuffer: DS 3 ; First byte is Count 0046 =1 63 CurrentConfiguration: 0046 =1 64 DS 1 ; Some examples support > 1 configurations =1 65 ; =1 66 ; Declare the specific variables used by each of the examples 0047 =1 67 Overlay EQU $ 0047 =1 68 Old_Buttons: DS 1 ; Used by BAL: stores current button position 0048 =1 69 LEDstrobe: DS 1 ; Used by BAL: strobe one LED on at a time 0049 =1 70 LEDvalue: DS 1 ; Used by BAL: stores current LED value 004A =1 71 Msec_Counter: DS 1 ; Used by BAL: counts up to 4 msec =1 72 0047 =1 73 ORG Overlay ; Overlay the variables (only one set in use at any one tim e) 0047 =1 74 I2CDataByte: DS 1 ; Used by I2C: keep a local copy of data read from I2C bus =1 75 0047 =1 76 ORG Overlay 0047 =1 77 LightValues: DS 6 ; Used by LP: local buffer for light brightness =1 78 0047 =1 79 ORG Overlay 0047 =1 80 CurrentPosition:DS 1 ; Used by Stepper: motor has 16 stable positions 0048 =1 81 MotorControl: DS 3 ; Used by Stepper: direction, Low(count) and High(count) =1 82 0047 =1 83 ORG Overlay 0047 =1 84 LimitValues: DS 12 ; Used by Temps: local buffer for limits =1 85 0047 =1 86 ORG Overlay 0047 =1 87 ButtonsValue: DS 1 ; Used by RB: buttons are read each full scan 0048 =1 88 DisplayPosition:DS 1 ; Used by RB: holds current display position 0049 =1 89 LEDBuffer: DS 42 ; Used by RB: local buffer for reader board =1 90 =1 91 ; 92 $INCLUDE(../Vectors.A51) =1 93 ; This module is common to all of the examples. =1 94 ; It contains all of the interrupt vector declarations and =1 95 ; the first level interrupt servicing (register save, call subroutine, =1 96 ; clear interrupt source, restore registers, return) =1 97 ; Suspend and Resume are handled totally in this module =1 98 ; =1 99 ; A Reset sends us to Program space location 0 ---- =1 100 CSEG AT 0 ; Code space =1 101 USING 0 ; Reset forces Register Bank 0 0000 0203D7 =1 102 LJMP Reset =1 103 ; =1 104 ; The interrupt vector table is also located here =1 105 ; EZ-USB has two levels of USB interrupts: =1 106 ; 1-the main level is described in this table (at ORG 43H) =1 107 ; 2-there are 21 sources of USB interrupts and these are described in USB_ISR =1 108 ; This means that two levels of acknowledgement and clearing will be required =1 109 ; LJMP INT0_ISR ; Features not used are commented out =1 110 ; ORG 0BH =1 111 ; LJMP Timer0_ISR =1 112 ; ORG 13H =1 113 ; LJMP INT1_ISR =1 114 ; ORG 1BH =1 115 ; LJMP Timer1_ISR =1 116 ; ORG 23H =1 117 ; LJMP UART0_ISR =1 118 ; ORG 2BH =1 119 ; LJMP Timer2_ISR =1 120 ; ORG 33H =1 121 ; LJMP WakeUp_ISR =1 122 ; ORG 3BH =1 123 ; LJMP UART1_ISR A51 MACRO ASSEMBLER RBDC 25/07/99 15:58:57 PAGE 3 0043 =1 124 ORG 43H 0043 020100 =1 125 LJMP USB_ISR ; Auto Vector will replace byte 45H =1 126 ; ORG 4BH =1 127 ; LJMP I2C_ISR =1 128 ; ORG 53H =1 129 ; LJMP INT4_ISR =1 130 ; ORG 5BH =1 131 ; LJMP INT5_ISR =1 132 ; ORG 63H =1 133 ; LJMP INT6_ISR =1 134 00E0 =1 135 ORG 0E0H ; Keep out of the way of dScope monitor =1 136 ; If you are not using dScope then this memory hole =1 137 ; may be used for useful routines. 0100 =1 138 ORG 100H 0100 02013C =1 139 USB_ISR:LJMP SUDAV_ISR 0103 00 =1 140 DB 0 ; Pad entries to 4 bytes 0104 020158 =1 141 LJMP SOF_ISR 0107 00 =1 142 DB 0 0108 020118 =1 143 LJMP SUTOK_ISR 010B 00 =1 144 DB 0 010C 020129 =1 145 LJMP Suspend_ISR 010F 00 =1 146 DB 0 0110 020120 =1 147 LJMP USBReset_ISR 0113 00 =1 148 DB 0 0114 020118 =1 149 LJMP Reserved 0117 00 =1 150 DB 0 =1 151 ; LJMP EP0In_ISR ; Endpoint Interrupts are not used in these examples =1 152 ; DB 0 ; Comment out features not used =1 153 ; LJMP EP0Out_ISR =1 154 ; DB 0 =1 155 ; LJMP EP1In_ISR =1 156 ; DB 0 =1 157 ; LJMP EP1Out_ISR =1 158 ; DB 0 =1 159 ; LJMP EP2In_ISR =1 160 ; DB 0 =1 161 ; LJMP EP2Out_ISR =1 162 ; DB 0 =1 163 ; LJMP EP3In_ISR =1 164 ; DB 0 =1 165 ; LJMP EP3Out_ISR =1 166 ; DB 0 =1 167 ; LJMP EP4In_ISR =1 168 ; DB 0 =1 169 ; LJMP EP4Out_ISR =1 170 ; DB 0 =1 171 ; LJMP EP5In_ISR =1 172 ; DB 0 =1 173 ; LJMP EP5Out_ISR =1 174 ; DB 0 =1 175 ; LJMP EP6In_ISR =1 176 ; DB 0 =1 177 ; LJMP EP6Out_ISR =1 178 ; DB 0 =1 179 ; LJMP EP7In_ISR =1 180 ; DB 0 =1 181 ; LJMP EP7Out_ISR =1 182 ; End of Interrupt Vector tables =1 183 =1 184 ; When a feature is used insert the required interrupt processing here =1 185 ; The example use only used Endpoints 0 and 1 and also SOF for timing 0118 =1 186 Reserved: 0118 =1 187 INT0_ISR: 0118 =1 188 Timer0_ISR: 0118 =1 189 INT1_ISR: A51 MACRO ASSEMBLER RBDC 25/07/99 15:58:57 PAGE 4 0118 =1 190 Timer1_ISR: 0118 =1 191 UART0_ISR: 0118 =1 192 Timer2_ISR: 0118 =1 193 UART1_ISR: 0118 =1 194 I2C_ISR: 0118 =1 195 INT4_ISR: 0118 =1 196 INT5_ISR: 0118 =1 197 INT6_ISR: 0118 =1 198 SUTOK_ISR: 0118 =1 199 EP0In_ISR: 0118 =1 200 EP0Out_ISR: 0118 =1 201 EP1In_ISR: 0118 =1 202 EP1Out_ISR: 0118 =1 203 EP2In_ISR: 0118 =1 204 EP2Out_ISR: 0118 =1 205 EP3In_ISR: 0118 =1 206 EP3Out_ISR: 0118 =1 207 EP4In_ISR: 0118 =1 208 EP4Out_ISR: 0118 =1 209 EP5In_ISR: 0118 =1 210 EP5Out_ISR: 0118 =1 211 EP6In_ISR: 0118 =1 212 EP6Out_ISR: 0118 =1 213 EP7In_ISR : 0118 =1 214 EP7Out_ISR: 0118 =1 215 Not_Used: ; Should not get any of these 0118 32 =1 216 RETI =1 217 0119 =1 218 ClearINT2: ; Tell the hardware that we're done 0119 E591 =1 219 MOV A, EXIF 011B C2E4 =1 220 CLR ACC.4 ; Clear the Interrupt 2 bit 011D F591 =1 221 MOV EXIF, A 011F 22 =1 222 RET =1 223 0120 =1 224 USBReset_ISR: ; Bus has been Reset, move to DEFAULT state 0120 C0E0 =1 225 PUSH ACC 0122 C200 =1 226 CLR Configured 0124 3119 =1 227 CALL ClearINT2 =1 228 ; No need to clear source of interrupt 0126 D0E0 =1 229 POP ACC 0128 32 =1 230 RETI =1 231 0129 =1 232 Suspend_ISR: ; SIE detected an Idle bus 0129 C0E0 =1 233 PUSH ACC 012B E587 =1 234 MOV A, PCON 012D 4401 =1 235 ORL A, #1 012F F587 =1 236 MOV PCON, A ; Go to sleep! 0131 00 =1 237 NOP 0132 00 =1 238 NOP ; Wake up here due to a USBResume 0133 00 =1 239 NOP 0134 3119 =1 240 CALL ClearINT2 0136 D0E0 =1 241 POP ACC 0138 32 =1 242 RETI =1 243 0139 =1 244 WakeUp_ISR: ; Not using external WAKEUP in these examples =1 245 ; So this must be due to a USBResume 0139 C2DC =1 246 CLR EICON.4 ; Clear the wakeup interrupt source 013B 32 =1 247 RETI =1 248 013C =1 249 SUDAV_ISR: ; A Setup packet has been received 013C C0D0 =1 250 PUSH PSW ; Save Registers before the service routine 013E C0E0 =1 251 PUSH ACC 0140 C082 =1 252 PUSH DPL 0142 C083 =1 253 PUSH DPH 0144 120169 =1 254 CALL ServiceSetupPacket 0147 3119 =1 255 CALL ClearINT2 A51 MACRO ASSEMBLER RBDC 25/07/99 15:58:57 PAGE 5 =1 256 ; Clear the source of the interrupt 0149 7401 =1 257 MOV A, #00000001b 014B 907FAB =1 258 ExitISR:MOV DPTR, #USBIRQ 014E F0 =1 259 MOVX @DPTR, A 014F D083 =1 260 POP DPH ; Restore Registers 0151 D082 =1 261 POP DPL 0153 D0E0 =1 262 POP ACC 0155 D0D0 =1 263 POP PSW 0157 32 =1 264 RETI =1 265 0158 =1 266 SOF_ISR: ; A Start-Of-Frame packet has been received 0158 C0D0 =1 267 PUSH PSW ; Save Registers before the service routine 015A C0E0 =1 268 PUSH ACC 015C C082 =1 269 PUSH DPL 015E C083 =1 270 PUSH DPH 0160 120683 =1 271 CALL ServiceTimerRoutine 0163 3119 =1 272 CALL ClearINT2 =1 273 ; Clear the source of the interrupt 0165 7402 =1 274 MOV A, #00000010b 0167 80E2 =1 275 JMP ExitISR =1 276 =1 277 278 $INCLUDE(USB_INT.A51) =1 279 ; This module is specific for the Dual Configuration example. =1 280 ; It services USB Requests from the SIE. =1 281 ; Interpretation of the Output Reports is handled by MAIN =1 282 ; ---- =1 283 CSEG 0169 =1 284 ServiceSetupPacket: 0169 907FE8 =1 285 MOV DPTR, #SETUPDAT ; Point to Setup Packet data 016C E0 =1 286 MOVX A, @DPTR ; Get the RequestType 016D A2E7 =1 287 MOV C, ACC.7 ; Bit 7 = 1 means IO device needs to send data to P C Host 016F 9202 =1 288 MOV SendData, C 0171 545C =1 289 ANL A, #01011100b ; IF RequestType[6.4.3.2] = 1 THEN goto BadRequest 0173 7051 =1 290 JNZ BadRequest 0175 E0 =1 291 MOVX A, @DPTR ; IF RequestType[1&0] = 1 THEN goto BadRequest 0176 A2E0 =1 292 MOV C, ACC.0 0178 82E1 =1 293 ANL C, ACC.1 017A 404A =1 294 JC BadRequest 017C 30E502 =1 295 JNB ACC.5, NotB5 ; IF RequestType[5] = 1 THEN RequestType[1,0] = [1, 1] 017F 7403 =1 296 MOV A, #00000011b 0181 5403 =1 297 NotB5: ANL A, #00000011b ; Set CommandIndex[5,4] = RequestType[1,0] 0183 C4 =1 298 SWAP A 0184 F540 =1 299 MOV Temp, A ; Save HI nibble of CommandIndex =1 300 ; Set CommandIndex[3,0] = Request[3,0] 0186 A3 =1 301 INC DPTR ; Point to Request 0187 E0 =1 302 MOVX A, @DPTR 0188 540F =1 303 ANL A, #00001111b ; Only 13 are defined today, handle in table 018A 4540 =1 304 ORL A, Temp 018C 1201D5 =1 305 CALL CorrectSubroutine ; goto CommandTable(CommandIndex) =1 306 ; Returns STALL=1 if a stall is required 018F 200134 =1 307 JB STALL, BadRequest 0192 300218 =1 308 JNB SendData, HandShake 0195 200320 =1 309 JB IsDescriptor, LoadSUDPTR; EZ-USB has a short cut for descriptors =1 310 ; Send data in ReplyBuffer 0198 907F02 =1 311 MOV DPTR, #EP0InBuffer+2 019B 7846 =1 312 MOV R0, #ReplyBuffer+3 019D 754003 =1 313 MOV Temp, #3 ; Copy maximum byte count 01A0 E6 =1 314 CopyRB: MOV A, @R0 01A1 F0 =1 315 MOVX @DPTR, A 01A2 1582 =1 316 DEC DPL 01A4 18 =1 317 DEC R0 01A5 D540F8 =1 318 DJNZ Temp, CopyRB 01A8 E6 =1 319 MOV A, @R0 ; Get real byte count A51 MACRO ASSEMBLER RBDC 25/07/99 15:58:57 PAGE 6 01A9 =1 320 SendEP0InBuffer: 01A9 907FB5 =1 321 MOV DPTR, #In0ByteCount 01AC =1 322 StartXfer: 01AC F0 =1 323 MOVX @DPTR, A ; This write initiates the transfer 01AD =1 324 HandShake: ; Handshake with host 01AD 754002 =1 325 MOV Temp, #00000010b ; Set HSNAK to tell the SIE that we're done 01B0 =1 326 SetEP0Control: 01B0 907FB4 =1 327 MOV DPTR, #EP0Control 01B3 E0 =1 328 MOVX A, @DPTR 01B4 4540 =1 329 ORL A, Temp 01B6 F0 =1 330 MOVX @DPTR, A 01B7 22 =1 331 RET 01B8 =1 332 LoadSUDPTR: ; Send the data pointed to by DPTR 01B8 858240 =1 333 MOV Temp, DPL 01BB E583 =1 334 MOV A, DPH 01BD 907FD4 =1 335 MOV DPTR, #SUDPTR 01C0 F0 =1 336 MOVX @DPTR, A 01C1 E540 =1 337 MOV A, Temp 01C3 A3 =1 338 INC DPTR 01C4 80E6 =1 339 JMP StartXfer 01C6 =1 340 BadRequest: ; Invalid Request was received 01C6 754003 =1 341 MOV Temp, #00000011b ; Set EP0STALL and HSNAK 01C9 80E5 =1 342 JMP SetEP0Control =1 343 01CB =1 344 NextDPTR: ; Returns (DPTR + byte DPTR is pointing to) 01CB E0 =1 345 MOVX A, @DPTR 01CC =1 346 BumpDPTR: ; Returns (DPTR + ACC) 01CC 2582 =1 347 ADD A, DPL 01CE F582 =1 348 MOV DPL, A 01D0 5002 =1 349 JNC Skip 01D2 0583 =1 350 INC DPH ; Need 16 bit arithmetic here 01D4 22 =1 351 Skip: RET =1 352 01D5 =1 353 CorrectSubroutine: ; Jump to the subroutine that DPTR is pointing to 01D5 9001FA =1 354 MOV DPTR, #CommandTable 01D8 31CC =1 355 CALL BumpDPTR ; Point to entry 01DA E0 =1 356 MOVX A, @DPTR ; Get the offset 01DB 9001FA =1 357 MOV DPTR, #CommandTable 01DE 31CC =1 358 CALL BumpDPTR ; Get the routine address 01E0 C082 =1 359 PUSH DPL ; Create a RETURN address on stack 01E2 C083 =1 360 PUSH DPH ; Note: JMP @A+DPTR not used since A, DPTR needed 01E4 7845 =1 361 MOV R0, #ReplyBuffer+2 01E6 E4 =1 362 CLR A 01E7 F6 =1 363 MOV @R0, A ; Clear ReplyBuffer 01E8 18 =1 364 DEC R0 01E9 F6 =1 365 MOV @R0, A 01EA 18 =1 366 DEC R0 01EB 7601 =1 367 MOV @R0, #1 ; Default non-descriptor reply 01ED 907FEA =1 368 MOV DPTR, #SETUPDAT+2 ; Point to LOW(wValue) 01F0 E0 =1 369 MOVX A, @DPTR ; Many of the routines need these 01F1 F5F0 =1 370 MOV B, A ; LOW(wValue) in B 01F3 A3 =1 371 INC DPTR 01F4 E0 =1 372 MOVX A, @DPTR ; HIGH(wValue) in A 01F5 C201 =1 373 CLR STALL 01F7 C203 =1 374 CLR IsDescriptor 01F9 22 =1 375 RET ; Go to service routine =1 376 =1 377 ; Since the table only contains byte offsets, it is important that all these routines are =1 378 ; within one page (100H) of CommandTable =1 379 ; 01FA =1 380 CommandTable: =1 381 ; First 16 commands are for the Device 01FA 71 =1 382 DB Device_Get_Status - CommandTable 01FB 40 =1 383 DB Device_Clear_Feature - CommandTable 01FC 40 =1 384 DB Invalid - CommandTable 01FD 40 =1 385 DB Device_Set_Feature - CommandTable A51 MACRO ASSEMBLER RBDC 25/07/99 15:58:57 PAGE 7 01FE 40 =1 386 DB Invalid - CommandTable 01FF 40 =1 387 DB Invalid - CommandTable ; SIE implements Device_Set_Address 0200 8A =1 388 DB Get_Descriptor - CommandTable 0201 40 =1 389 DB Set_Descriptor - CommandTable 0202 6A =1 390 DB Get_Configuration - CommandTable 0203 78 =1 391 DB Set_Configuration - CommandTable 0204 40 =1 392 DB Invalid - CommandTable 0205 40 =1 393 DB Invalid - CommandTable 0206 40 =1 394 DB Invalid - CommandTable 0207 40 =1 395 DB Invalid - CommandTable 0208 40 =1 396 DB Invalid - CommandTable 0209 40 =1 397 DB Invalid - CommandTable =1 398 ; Next 16 commands are for the Interface 020A 75 =1 399 DB Interface_Get_Status - CommandTable 020B 40 =1 400 DB Interface_Clear_Feature - CommandTable 020C 40 =1 401 DB Invalid - CommandTable 020D 40 =1 402 DB Interface_Set_Feature - CommandTable 020E 40 =1 403 DB Invalid - CommandTable 020F 40 =1 404 DB Invalid - CommandTable 0210 B4 =1 405 DB Get_Class_Descriptor - CommandTable 0211 40 =1 406 DB Set_Class_Descriptor - CommandTable 0212 40 =1 407 DB Invalid - CommandTable 0213 40 =1 408 DB Invalid - CommandTable 0214 40 =1 409 DB Get_Interface - CommandTable 0215 40 =1 410 DB Set_Interface - CommandTable 0216 40 =1 411 DB Invalid - CommandTable 0217 40 =1 412 DB Invalid - CommandTable 0218 40 =1 413 DB Invalid - CommandTable 0219 40 =1 414 DB Invalid - CommandTable =1 415 ; Next 16 commands are for the Endpoint 021A 75 =1 416 DB Endpoint_Get_Status - CommandTable 021B 42 =1 417 DB Endpoint_Clear_Feature - CommandTable 021C 40 =1 418 DB Invalid - CommandTable 021D 40 =1 419 DB Endpoint_Set_Feature - CommandTable 021E 40 =1 420 DB Invalid - CommandTable 021F 40 =1 421 DB Invalid - CommandTable 0220 40 =1 422 DB Invalid - CommandTable 0221 40 =1 423 DB Invalid - CommandTable 0222 40 =1 424 DB Invalid - CommandTable 0223 40 =1 425 DB Invalid - CommandTable 0224 40 =1 426 DB Invalid - CommandTable 0225 40 =1 427 DB Invalid - CommandTable 0226 40 =1 428 DB Endpoint_Sync_Frame - CommandTable 0227 40 =1 429 DB Invalid - CommandTable 0228 40 =1 430 DB Invalid - CommandTable 0229 40 =1 431 DB Invalid - CommandTable =1 432 ; Next 16 commands are Class Requests 022A 40 =1 433 DB Invalid - CommandTable 022B 56 =1 434 DB Get_Report - CommandTable 022C 63 =1 435 DB Get_Idle - CommandTable 022D 40 =1 436 DB Get_Protocol - CommandTable 022E 40 =1 437 DB Invalid - CommandTable 022F 40 =1 438 DB Invalid - CommandTable 0230 40 =1 439 DB Invalid - CommandTable 0231 40 =1 440 DB Invalid - CommandTable 0232 40 =1 441 DB Invalid - CommandTable 0233 43 =1 442 DB Set_Report - CommandTable 0234 5D =1 443 DB Set_Idle - CommandTable 0235 40 =1 444 DB Set_Protocol - CommandTable 0236 40 =1 445 DB Invalid - CommandTable 0237 40 =1 446 DB Invalid - CommandTable 0238 40 =1 447 DB Invalid - CommandTable 0239 40 =1 448 DB Invalid - CommandTable =1 449 ; =1 450 ; Many requests are INVALID for this example 023A =1 451 Get_Protocol: ; We are not a Boot device A51 MACRO ASSEMBLER RBDC 25/07/99 15:58:57 PAGE 8 023A =1 452 Set_Protocol: ; We are not a Boot device 023A =1 453 Set_Descriptor: ; Our Descriptors are static 023A =1 454 Set_Class_Descriptor: ; Our Descriptors are static 023A =1 455 Set_Interface: ; We only have one Interface 023A =1 456 Get_Interface: ; We do not have an Alternate setting 023A =1 457 Device_Set_Feature: ; We have no features that can be set or cleared 023A =1 458 Interface_Set_Feature: ; We have no features that can be set or cleared 023A =1 459 Endpoint_Set_Feature: ; We have no features that can be set or cleared 023A =1 460 Device_Clear_Feature: ; We have no features that can be set or cleared 023A =1 461 Interface_Clear_Feature: ; We have no features that can be set or cleared 023A =1 462 Endpoint_Sync_Frame: ; We are not an Isonchronous device =1 463 023A =1 464 Invalid: ; Invalid Request made, STALL the Endpoint 023A D201 =1 465 SETB STALL =1 466 ; 023C =1 467 Endpoint_Clear_Feature: ; We have no features that can be set or cleared =1 468 ; 023C 22 =1 469 Reply: RET =1 470 023D =1 471 Set_Report: ; Host wants to sent us a Report. =1 472 ; The ONLY case in this example where host sends data to us 023D 3000FA =1 473 JNB Configured, Invalid ; Need to be Configured to do this command 0240 907FC5 =1 474 MOV DPTR, #Out0ByteCount ; Enable EP0OutBuffer to receive data 0243 F0 =1 475 MOVX @DPTR, A ; Any value will do 0244 907FAA =1 476 MOV DPTR, #OUT07IRQ ; Wait for valid data in EP0OutBuffer 0247 E0 =1 477 Wait4D: MOVX A, @DPTR 0248 5401 =1 478 ANL A, #00000001b 024A 60FB =1 479 JZ Wait4D 024C F0 =1 480 MOVX @DPTR, A ; Clear the interrupt 024D 02043F =1 481 JMP ProcessOutputReport ; RETurn via this subroutine 0250 =1 482 Get_Report: ; Host wants a Report 0250 3000E7 =1 483 JNB Configured, Invalid ; Need to be Configured to do this command 0253 08 =1 484 INC R0 ; Point to ReplyBuffer(1) 0254 7618 =1 485 MOV @R0, #18H ; Reply with a recognizable (arbitary) value 0256 22 =1 486 RET 0257 =1 487 Set_Idle: ; Host wants to tell us how often we should talk 0257 3000E0 =1 488 JNB Configured, Invalid ; Need to be Configured to do this command 025A F541 =1 489 MOV Idle_Time, A 025C 22 =1 490 RET ; Handshake with host 025D =1 491 Get_Idle: ; Host must have forgotten what he told us to do 025D 3000DA =1 492 JNB Configured, Invalid ; Need to be Configured to do this command 0260 08 =1 493 INC R0 ; Point to ReplyBuffer(1) 0261 A641 =1 494 MOV @R0, Idle_Time 0263 22 =1 495 RET 0264 =1 496 Get_Configuration: 0264 3000D5 =1 497 JNB Configured, Reply 0267 08 =1 498 INC R0 0268 A646 =1 499 MOV @R0, CurrentConfiguration 026A 22 =1 500 RET 026B =1 501 Device_Get_Status: ; Only two bits of Device Status are defined 026B 08 =1 502 INC R0 ; Point to ReplyBuffer(1) 026C 7601 =1 503 MOV @R0, #1 ; Bit 1=Remote Wakeup(=0), Bit 0=Self Powered(=1) 026E 22 =1 504 RET 026F =1 505 Interface_Get_Status: ; Interface Status is currently defined as 0 026F =1 506 Endpoint_Get_Status: 026F 7602 =1 507 MOV @R0, #2 0271 22 =1 508 RET 0272 =1 509 Set_Configuration: ; Valid values are 0 and 1 0272 E5F0 =1 510 MOV A, B ; Get LOW(wValue) 0274 600B =1 511 JZ Deconfigured 0276 C3 =1 512 CLR C 0277 9503 =1 513 SUBB A, ConfigurationCount+1 ; This example supports two configurations 0279 50BF =1 514 JNC Invalid 027B 85F046 =1 515 MOV CurrentConfiguration, B 027E D200 =1 516 SETB Configured 0280 22 =1 517 RET A51 MACRO ASSEMBLER RBDC 25/07/99 15:58:57 PAGE 9 0281 =1 518 Deconfigured: 0281 C200 =1 519 CLR Configured 0283 22 =1 520 Reply2: RET 0284 =1 521 Get_Descriptor: ; Host wants to know who/what we are 0284 D203 =1 522 SETB IsDescriptor 0286 14 =1 523 DEC A ; Valid Values are 1, 2 and 3 0287 9002E0 =1 524 MOV DPTR, #DeviceDescriptor 028A 60B0 =1 525 JZ Reply 028C 14 =1 526 DEC A 028D 9002F2 =1 527 MOV DPTR, #TextConfigurationDescriptor 0290 30F103 =1 528 JNB B.1, Other1 ; B = Descriptor Index (=1 or 2) 0293 900333 =1 529 MOV DPTR, #DotConfigurationDescriptor 0296 60A4 =1 530 Other1: JZ Reply 0298 14 =1 531 DEC A 0299 709F =1 532 JNZ Invalid =1 533 ; Request is for a String Descriptor 029B 900365 =1 534 MOV DPTR, #String0 ; Point to String 0 029E E5F0 =1 535 MOV A, B ; Get String Index 02A0 =1 536 NextString: 02A0 602A =1 537 JZ FixUpthenReply 02A2 F540 =1 538 MOV Temp, A ; Save String Index 02A4 31CB =1 539 CALL NextDPTR 02A6 E0 =1 540 MOVX A, @DPTR ; Get the String Length (= 0 means we're at Backsto p) 02A7 6091 =1 541 JZ Invalid ; Asked for a string I don't have 02A9 E540 =1 542 MOV A, Temp 02AB 14 =1 543 DEC A 02AC 80F2 =1 544 JMP NextString ; Check if we are there yet 02AE =1 545 Get_Class_Descriptor: ; Valid values are 21H, 22H, 23H for Class Request 02AE D203 =1 546 SETB IsDescriptor 02B0 C3 =1 547 CLR C 02B1 9421 =1 548 SUBB A, #21H 02B3 900304 =1 549 MOV DPTR, #TextHIDDescriptor 02B6 30F103 =1 550 JNB B.1, Other2 ; B = Descriptor Index (=1 or 2) 02B9 900345 =1 551 MOV DPTR, #DotHIDDescriptor 02BC 60C5 =1 552 Other2: JZ Reply2 02BE 14 =1 553 DEC A 02BF 900314 =1 554 MOV DPTR, #TextReportDescriptor 02C2 30F103 =1 555 JNB B.1, Other3 ; B = Descriptor Index (=1 or 2) 02C5 90034E =1 556 MOV DPTR, #DotReportDescriptor 02C8 60B9 =1 557 Other3: JZ Reply2 =1 558 ; DEC A ; This example does not use Physical Descriptors =1 559 ; JZ Send_Physical_Descriptor 02CA 413A =1 560 JMP Invalid =1 561 ; =1 562 ; Error check: this MUST be on within a page of CommandTable 00D2 =1 563 WithinSamePage EQU $ - CommandTable =1 564 ; 02CC =1 565 FixUpthenReply: ; EZ-USB Rev D has a String Descriptor bug =1 566 ; Need to fill the IN0BUF (@ 7F00H) myself 02CC E0 =1 567 MOVX A, @DPTR ; Get the string length 02CD FF =1 568 MOV R7, A ; Save counter 02CE F5F0 =1 569 MOV B, A 02D0 7800 =1 570 MOV R0, #LOW(EP0InBuffer) ; PageReg = 7FH = HIGH(EP0InBuffer) 02D2 F2 =1 571 CopySD: MOVX @R0, A 02D3 08 =1 572 INC R0 02D4 A3 =1 573 INC DPTR 02D5 E0 =1 574 MOVX A, @DPTR 02D6 DFFA =1 575 DJNZ R7, CopySD =1 576 ; Fixup complete, get back to the program flow 02D8 D0E0 =1 577 POP ACC ; Get rid of the return address 02DA D0E0 =1 578 POP ACC 02DC E5F0 =1 579 MOV A, B ; Retrieve byte count 02DE 21A9 =1 580 JMP SendEP0InBuffer 581 $INCLUDE(DTables.A51) =1 582 ; This module declares the descriptors A51 MACRO ASSEMBLER RBDC 25/07/99 15:58:57 PAGE 10 =1 583 ; =1 584 ; This example has one Device Descriptor with TWO Configurations 0002 =1 585 ConfigurationCount EQU 2 =1 586 ; Dot Mode: the IO device accepts RAW dots for the display =1 587 ; One Interface - there is only one method of accessing the ports =1 588 ; One HID Descriptor - to make PC host software simpler =1 589 ; One Report Descriptor - 40 byte OUT report =1 590 ; Text mode: the IO device accepts ASCII characters for display =1 591 ; One Interface - there is only one method of accessing the ports =1 592 ; One HID Descriptor - to make PC host software simpler =1 593 ; One Endpoint Descriptor - for HID Input Reports =1 594 ; One Report Descriptor - 40 byte IN and 7 byte OUT reports =1 595 ; Multiple Sting Descriptors - to aid the user =1 596 ; =1 597 ; PROBLEM: during system testing it was discovered that Windows 98 DOES NOT SUPPORT the =1 598 ; HidD_GetConfiguration system call - this means that an application program (which is what =1 599 ; this is) CANNOT send a SetConfiguration packet to an I/O device; the call is supported =1 600 ; by Windows 2000 and by Windows 98 for kernel level (ie device driver) software. =1 601 ; The "Reader Board" I/O device was tested independantly for its correct dual-configuration =1 602 ; operation. =1 603 ; This example, therefore, uses an ALTERNATE method of implementing "dual-configuration" =1 604 ; I extended the Report Buffer by one byte and prepend the data with the "mode" byte. =1 605 ; This works, not as elegant as I would have wanted, but it does implement "dual-modes" =1 606 ; The "default" configuration (=1) is Text mode so that we have an INPUT Report ---- =1 607 CSEG 02E0 =1 608 DeviceDescriptor: 02E0 1201 =1 609 DB 18, 1 ; Length, Type 02E2 0101 =1 610 DW 101H ; USB Rev 1.1 02E4 000000 =1 611 DB 0, 0, 0 ; Class, Subclass and Protocol 02E7 40 =1 612 DB 64 ; EP0 size 02E8 4242 =1 613 DW 4242H, 1, 1 ; Vendor ID, Product ID and Version 02EA 0001 02EC 0001 02EE 010200 =1 614 DB 1, 2, 0 ; Manufacturer, Product & Serial# Names 02F1 02 =1 615 DB ConfigurationCount; #Configs =1 616 02F2 =1 617 TextConfigurationDescriptor: 02F2 0902 =1 618 DB 9, 2 ; Length, Type 02F4 2200 =1 619 DB LOW(TextConfigLength), HIGH(TextConfigLength) 02F6 010103 =1 620 DB 1, 1, 3 ; #Interfaces, Configuration#, Config. Name 02F9 80 =1 621 DB 10000000b ; Attributes = Bus Powered 02FA 32 =1 622 DB 50 ; Max. Power is 50x2 = 100mA 02FB =1 623 TextInterfaceDescriptor: 02FB 0904 =1 624 DB 9, 4 ; Length, Type 02FD 000001 =1 625 DB 0, 0, 1 ; No alternate setting, HID Input uses EP1 0300 03 =1 626 DB 3 ; Class = Human Interface Device 0301 0000 =1 627 DB 0, 0 ; Subclass and Protocol 0303 00 =1 628 DB 0 ; Interface Name 0304 =1 629 TextHIDDescriptor: 0304 0921 =1 630 DB 9, 21H ; Length, Type 0306 0001 =1 631 DB 0, 1 ; HID Class Specification compliance 0308 00 =1 632 DB 0 ; Country localization (=none) 0309 01 =1 633 DB 1 ; Number of descriptors to follow 030A 22 =1 634 DB 22H ; And it's a Report descriptor 030B 1F00 =1 635 DB LOW(TextReportLength), HIGH(TextReportLength) 030D =1 636 TextEndpointDescriptor: 030D 0705 =1 637 DB 7, 5 ; Length, Type 030F 81 =1 638 DB 10000001b ; Address = IN 1 0310 03 =1 639 DB 00000011b ; Interrupt 0311 4000 =1 640 DB 64, 0 ; Maximum packet size 0313 64 =1 641 DB 100 ; Poll every 0.1 seconds 0022 =1 642 TextConfigLength EQU $ - TextConfigurationDescriptor =1 643 0314 =1 644 TextReportDescriptor: ; Generated with HID Tool, copied to here 0314 0600FF =1 645 DB 6, 0, 0FFH ; Usage_Page (Vendor Defined) 0317 0901 =1 646 DB 9, 1 ; Usage (I/O Device) A51 MACRO ASSEMBLER RBDC 25/07/99 15:58:57 PAGE 11 0319 A101 =1 647 DB 0A1H, 1 ; Collection (Application) 031B 1901 =1 648 DB 19H, 1 ; Usage_Minimum 031D 2902 =1 649 DB 29H, 2 ; Usage_Maximum 031F 1500 =1 650 DB 15H, 0 ; Logical_Minimum (0) 0321 26FF00 =1 651 DB 26H, 255, 0 ; Logical_Maximum (255) 0324 7508 =1 652 DB 75H, 8 ; Report_Size (8) 0326 9528 =1 653 DB 95H, 40 ; Report_Count (40) 0328 8102 =1 654 DB 81H, 2 ; Input (Data,Var,Abs) = DOTs 032A 1901 =1 655 DB 19H, 1 ; Usage_Minimum 032C 2902 =1 656 DB 29H, 2 ; Usage_Maximum 032E 9529 =1 657 DB 95H, 41 ; Report_Count (7) =1 658 ; Report Count Change: See comment re-SetConfiguration 0330 9102 =1 659 DB 91H, 2 ; Output (Data,Var,Abs) = Text 0332 C0 =1 660 DB 0C0H ; End_Collection 001F =1 661 TextReportLength EQU $-TextReportDescriptor =1 662 0333 =1 663 DotConfigurationDescriptor: 0333 0902 =1 664 DB 9, 2 ; Length, Type 0335 1B00 =1 665 DB LOW(DotConfigLength), HIGH(DotConfigLength) 0337 010204 =1 666 DB 1, 2, 4 ; #Interfaces, Configuration#, Config. Name 033A 80 =1 667 DB 10000000b ; Attributes = Bus Powered 033B 32 =1 668 DB 50 ; Max. Power is 50x2 = 100mA 033C =1 669 DotInterfaceDescriptor: 033C 0904 =1 670 DB 9, 4 ; Length, Type 033E 000000 =1 671 DB 0, 0, 0 ; No alternate setting, HID Output Report uses EP0 0341 03 =1 672 DB 3 ; Class = Human Interface Device 0342 0000 =1 673 DB 0, 0 ; Subclass and Protocol 0344 00 =1 674 DB 0 ; Interface Name 0345 =1 675 DotHIDDescriptor: 0345 0921 =1 676 DB 9, 21H ; Length, Type 0347 0001 =1 677 DB 0, 1 ; HID Class Specification compliance 0349 00 =1 678 DB 0 ; Country localization (=none) 034A 01 =1 679 DB 1 ; Number of descriptors to follow 034B 22 =1 680 DB 22H ; And it's a Report descriptor 034C 1700 =1 681 DB LOW(DotReportLength), HIGH(DotReportLength) 001B =1 682 DotConfigLength EQU $ - DotConfigurationDescriptor =1 683 034E =1 684 DotReportDescriptor: ; Generated with HID Tool, copied to here 034E 0600FF =1 685 DB 6, 0, 0FFH ; Usage_Page (Vendor Defined) 0351 0901 =1 686 DB 9, 1 ; Usage (I/O Device) 0353 A101 =1 687 DB 0A1H, 1 ; Collection (Application) 0355 1901 =1 688 DB 19H, 1 ; Usage_Minimum 0357 2902 =1 689 DB 29H, 2 ; Usage_Maximum 0359 1500 =1 690 DB 15H, 0 ; Logical_Minimum (0) 035B 26FF00 =1 691 DB 26H, 255, 0 ; Logical_Maximum (255) 035E 7508 =1 692 DB 75H, 8 ; Report_Size (8) 0360 9529 =1 693 DB 95H, 41 ; Report_Count (41) =1 694 ; Report Count Change: See comment re-SetConfiguration 0362 9102 =1 695 DB 91H, 2 ; Output (Data,Var,Abs) = DOTs 0364 C0 =1 696 DB 0C0H ; End_Collection 0017 =1 697 DotReportLength EQU $-DotReportDescriptor =1 698 0365 =1 699 String0: ; Declare the UNICODE strings 0365 04030904 =1 700 DB 4, 3, 9, 4 ; Only English language strings supported 0369 =1 701 String1: ; Manufacturer 0369 2C03 =1 702 DB (String2-String1),3 ; Length, Type 036B 55005300 =1 703 DB "U",0,"S",0,"B",0," ",0,"D",0,"e",0,"s",0,"i",0,"g",0,"n",0," ", 0 036F 42002000 0373 44006500 0377 73006900 037B 67006E00 037F 2000 0381 42007900 =1 704 DB "B",0,"y",0," ",0,"E",0,"x",0,"a",0,"m",0,"p",0,"l",0,"e",0 0385 20004500 0389 78006100 038D 6D007000 A51 MACRO ASSEMBLER RBDC 25/07/99 15:58:57 PAGE 12 0391 6C006500 0395 =1 705 String2: ; Product Name 0395 1A03 =1 706 DB (String3-String2),3 0397 52006500 =1 707 DB "R",0,"e",0,"a",0,"d",0,"e",0,"r",0 039B 61006400 039F 65007200 03A3 20004200 =1 708 DB " ",0,"B",0,"o",0,"a",0,"r",0,"d",0 03A7 6F006100 03AB 72006400 03AF =1 709 String3: ; Configuration Name 03AF 1403 =1 710 DB (String4-String3),3 03B1 54006500 =1 711 DB "T",0,"e",0,"x",0,"t",0," ",0,"M",0,"o",0,"d",0,"e",0 03B5 78007400 03B9 20004D00 03BD 6F006400 03C1 6500 03C3 =1 712 String4: ; Configuration Name 03C3 1203 =1 713 DB (EndOfDescriptors-String4),3 03C5 44006F00 =1 714 DB "D",0,"o",0,"t",0," ",0,"M",0,"o",0,"d",0,"e",0 03C9 74002000 03CD 4D006F00 03D1 64006500 03D5 =1 715 EndOfDescriptors: 03D5 0000 =1 716 DW 0 ; Backstop for String Descriptors =1 717 =1 718 =1 719 720 $INCLUDE(Main.A51) =1 721 ; This module initializes the microcontroller then executes MAIN forever =1 722 ; =1 723 03D7 =1 724 Reset: 03D7 7581EB =1 725 MOV SP, #235 ; Initialize the Stack at top of internal memory 03DA 75927F =1 726 MOV PageReg, #7FH ; Needed to use MOVX @Ri =1 727 03DD 78D6 =1 728 MOV R0, #LOW(USBControl) ; Simulate a disconnect 03DF E2 =1 729 MOVX A, @R0 03E0 54F3 =1 730 ANL A, #11110011b ; Clear DISCON, DISCOE 03E2 F2 =1 731 MOVX @R0, A 03E3 12042E =1 732 CALL Wait100msec ; Give the host time to react 03E6 E2 =1 733 MOVX A, @R0 ; Reconnect with this new identity 03E7 4406 =1 734 ORL A, #00000110b ; Set DISCOE to enable pullup resistor 03E9 F2 =1 735 MOVX @R0, A ; Set RENUM so that 8051 handles USB requests 03EA E4 =1 736 CLR A 03EB F520 =1 737 MOV FLAGS, A ; Start in Default state 03ED F546 =1 738 MOV CurrentConfiguration, A ; This example supports two configurations 03EF 7848 =1 739 MOV R0, #DisplayPosition ; Note LEDBuffer follows DisplayPosition 03F1 7F2B =1 740 MOV R7, #43 03F3 7408 =1 741 MOV A, #8 ; Display a horizontal line 03F5 =1 742 ClearDisplay: 03F5 F6 =1 743 MOV @R0, A 03F6 08 =1 744 INC R0 03F7 DFFC =1 745 DJNZ R7, ClearDisplay =1 746 03F9 =1 747 InitializeIOSystem: ; This example uses PortA an IN/OUT and =1 748 ; the lower 4 bits of PortC as OUT =1 749 ; Assume a pre-existing configuration (ie Dscope) 03F9 7893 =1 750 MOV R0, #LOW(PortA_Config) ; PageReg = 7F = HIGH(PortA_Config) 03FB E4 =1 751 CLR A 03FC F2 =1 752 MOVX @R0, A ; No alternate functions 03FD 799C =1 753 MOV R1, #LOW(PortA_OE) 03FF F4 =1 754 CPL A ; = 0FFH 0400 F3 =1 755 MOVX @R1, A ; Enable PortA for Output 0401 7895 =1 756 MOV R0, #LOW(PortC_Config) ; PageReg = 7F = HIGH(PortC_Config) 0403 799E =1 757 MOV R1, #LOW(PortC_OE) 0405 E2 =1 758 MOVX A, @R0 ; Get current configuration A51 MACRO ASSEMBLER RBDC 25/07/99 15:58:57 PAGE 13 0406 54F0 =1 759 ANL A, #0F0H 0408 F2 =1 760 MOVX @R0, A ; No alternate functions on lower nibble 0409 E3 =1 761 MOVX A, @R1 ; Get current configuration 040A 440F =1 762 ORL A, #0FH 040C F3 =1 763 MOVX @R1, A ; Enable PortC_Bits[3:0] for Output 040D 7898 =1 764 MOV R0, #LOW(PortC_Out) 040F E2 =1 765 MOVX A, @R0 0410 54F0 =1 766 ANL A, #0F0H 0412 F2 =1 767 MOVX @R0, A ; Set Bits [3:0] low =1 768 0413 =1 769 InitializeInterruptSystem: ; First initialize the USB level 0413 78AC =1 770 MOV R0, #LOW(IN07IEN) 0415 F2 =1 771 MOVX @R0, A ; Disable interrupts from IN Endpoints 0-7 0416 08 =1 772 INC R0 0417 F2 =1 773 MOVX @R0, A ; Disable interrupts from OUT Endpoints 0-7 0418 08 =1 774 INC R0 0419 7403 =1 775 MOV A, #00000011b 041B F2 =1 776 MOVX @R0, A ; Enable (Resume, Suspend,) SOF and SUDAV INTs 041C 08 =1 777 INC R0 041D 7401 =1 778 MOV A, #00000001b 041F F2 =1 779 MOVX @R0, A ; Enable Auto Vectoring for USB interrupts 0420 78AA =1 780 MOV R0, #LOW(OUT07IRQ) 0422 74FF =1 781 MOV A, #0FFH 0424 F2 =1 782 MOVX @R0, A ; Clear out any pending interrupts =1 783 ; Now enable the main level 0425 75E801 =1 784 MOV EIE, #00000001b ; Enable INT2 = USB Interrupt (only) 0428 75A8C0 =1 785 MOV EI, #11000000b ; Enable interrupt subsystem (and Ser1 for Dscope) =1 786 =1 787 ; Initialization Complete. =1 788 ; 042B =1 789 MAIN: 042B 00 =1 790 NOP ; Not much of a main loop for this example 042C 80FD =1 791 JMP MAIN ; All actions are initiated by interrupts =1 792 ; We are a slave, we wait to be told what to do =1 793 042E =1 794 Wait100msec: 042E 754064 =1 795 MOV Temp, #100 0431 =1 796 Wait1msec: ; A delay loop 0431 90FB50 =1 797 MOV DPTR, #-1200 0434 A3 =1 798 More: INC DPTR ; 3 cycles 0435 E582 =1 799 MOV A, DPL ; + 2 0437 4583 =1 800 ORL A, DPH ; + 2 0439 70F9 =1 801 JNZ More ; + 3 = 10 cycles x 1200 = 1msec 043B D540F3 =1 802 DJNZ Temp, Wait1msec 043E 22 =1 803 RET =1 804 043F =1 805 ProcessOutputReport: ; A Report has just been received =1 806 ; See comment re SetConfiguration in DTables.A51 043F 907EC0 =1 807 MOV DPTR, #EP0OutBuffer 0442 E0 =1 808 MOVX A, @DPTR =1 809 =1 810 ; The interpretation of the Report is different depending upon the MODE we are in =1 811 ; MOV A, CurrentConfiguration 0443 B4020D =1 812 CJNE A, #2, TextMode =1 813 0446 =1 814 DOTmode: =1 815 ; The report is 41 bytes long and is a mode byte then a buffer 0446 907EC1 =1 816 MOV DPTR, #EP0OutBuffer+1 ; Point to the Report (after Mode Byte) 0449 7849 =1 817 MOV R0, #LEDBuffer 044B E0 =1 818 MOVX A, @DPTR 044C 7F28 =1 819 MOV R7, #40 ; Have room for 40 Columns 044E E0 =1 820 DMLoop: MOVX A, @DPTR ; Update the local buffer 044F F6 =1 821 MOV @R0, A 0450 DFFC =1 822 DJNZ R7, DMloop 0452 22 =1 823 RET =1 824 A51 MACRO ASSEMBLER RBDC 25/07/99 15:58:57 PAGE 14 0453 =1 825 TextMode: =1 826 ; The report is 7 characters long and must be translated into a dot pattern 0453 758601 =1 827 MOV DPS, #1 ; Select the other Data Pointer 0456 907EC1 =1 828 MOV DPTR, #EP0OutBuffer+1 ; Point to the Report 0459 7849 =1 829 MOV R0, #LEDBuffer 045B 7F07 =1 830 MOV R7, #7 ; Have room for 7 characters 045D E0 =1 831 ORLoop: MOVX A, @DPTR 045E 30E702 =1 832 JNB ACC.7, Skip1 ; Valid Characters are 20H to 7FH 0461 743F =1 833 MOV A, #3FH ; Replace characters > 7FH with ? 0463 C3 =1 834 Skip1: CLR C 0464 9420 =1 835 SUBB A, #20H 0466 5002 =1 836 JNC Skip2 0468 743C =1 837 MOV A, #3CH ; Replace characters < 20H with [] 046A 75F005 =1 838 Skip2: MOV B, #5 046D A4 =1 839 MUL AB ; B = HI((Char-20H)*5), A = LOW 046E 0586 =1 840 INC DPS ; Swap to "other" DPTR 0470 9004A3 =1 841 MOV DPTR, #LookupTable 0473 2582 =1 842 ADD A, DPL 0475 F582 =1 843 MOV DPL, A 0477 E5F0 =1 844 MOV A, B 0479 3583 =1 845 ADDC A, DPH 047B F583 =1 846 MOV DPH, A ; DPTR now pointing into Lookup Table 047D 7E05 =1 847 MOV R6, #5 047F E0 =1 848 LTCopy: MOVX A, @DPTR 0480 F6 =1 849 MOV @R0, A 0481 A3 =1 850 INC DPTR 0482 08 =1 851 INC R0 0483 DEFA =1 852 DJNZ R6, LTCopy 0485 7600 =1 853 MOV @R0, #0 ; Put a space between characters 0487 08 =1 854 INC R0 0488 0586 =1 855 INC DPS ; Switch to DPTR1 048A A3 =1 856 INC DPTR ; Point to next character in Output Report 048B DFD0 =1 857 DJNZ R7, ORLoop 048D 0586 =1 858 INC DPS ; Return DPTR to DPTR0 =1 859 ; Fall into CreateInputReport 048F =1 860 CreateInputReport: =1 861 ; The report is 40 bytes long in this example =1 862 ; It contains the LED Buffer 048F 907E80 =1 863 MOV DPTR, #EP1InBuffer ; Point to the buffer 0492 7849 =1 864 MOV R0, #LEDBuffer 0494 7F28 =1 865 MOV R7, #40 0496 E6 =1 866 IRLoop: MOV A, @R0 0497 F0 =1 867 MOVX @DPTR, A 0498 A3 =1 868 INC DPTR 0499 08 =1 869 INC R0 049A DFFA =1 870 DJNZ R7, IRLoop 049C 907FB7 =1 871 MOV DPTR, #IN1ByteCount 049F 7428 =1 872 MOV A, #40 04A1 F0 =1 873 MOVX @DPTR, A ; Endpoint 1 now 'armed', next IN will get data 04A2 22 =1 874 RET =1 875 04A3 =1 876 LookupTable: ; Contains the 5 columns of the 7x5 display 04A3 00000000 =1 877 DB 00H,00H,00H,00H,00H ; SPACE 04A7 00 04A8 00007D00 =1 878 DB 00H,00H,7DH,00H,00H ; ! 04AC 00 04AD 00700070 =1 879 DB 00H,70H,00H,70H,00H ; " 04B1 00 04B2 147F147F =1 880 DB 14H,7FH,14H,7FH,14H ; # 04B6 14 04B7 122A7F2A =1 881 DB 12H,2AH,7FH,2AH,24H ; $ 04BB 24 04BC 62640813 =1 882 DB 62H,64H,08H,13H,23H ; % 04C0 23 04C1 36495522 =1 883 DB 36H,49H,55H,22H,05H ; & 04C5 05 A51 MACRO ASSEMBLER RBDC 25/07/99 15:58:57 PAGE 15 04C6 00506000 =1 884 DB 00H,50H,60H,00H,00H ; ' 04CA 00 04CB 001C2241 =1 885 DB 00H,1CH,22H,41H,00H ; ( 04CF 00 04D0 0041221C =1 886 DB 00H,41H,22H,1CH,00H ; ) 04D4 00 04D5 14083E08 =1 887 DB 14H,08H,3EH,08H,14H ; * 04D9 14 04DA 08083E08 =1 888 DB 08H,08H,3EH,08H,08H ; + 04DE 08 04DF 00050600 =1 889 DB 00H,05H,06H,00H,00H ; , 04E3 00 04E4 08080808 =1 890 DB 08H,08H,08H,08H,08H ; - 04E8 08 04E9 00030300 =1 891 DB 00H,03H,03H,00H,00H ; . 04ED 00 04EE 02040810 =1 892 DB 02H,04H,08H,10H,20H ; / 04F2 20 04F3 3E454951 =1 893 DB 3EH,45H,49H,51H,3EH ; 0 04F7 3E 04F8 00217F01 =1 894 DB 00H,21H,7FH,01H,00H ; 1 04FC 00 04FD 21434549 =1 895 DB 21H,43H,45H,49H,31H ; 2 0501 31 0502 42415169 =1 896 DB 42H,41H,51H,69H,46H ; 3 0506 46 0507 0C14247F =1 897 DB 0CH,14H,24H,7FH,04H ; 4 050B 04 050C 72515151 =1 898 DB 72H,51H,51H,51H,4EH ; 5 0510 4E 0511 1E294949 =1 899 DB 1EH,29H,49H,49H,06H ; 6 0515 06 0516 40474850 =1 900 DB 40H,47H,48H,50H,60H ; 7 051A 60 051B 36494949 =1 901 DB 36H,49H,49H,49H,36H ; 8 051F 36 0520 3049494A =1 902 DB 30H,49H,49H,4AH,3CH ; 9 0524 3C 0525 00333300 =1 903 DB 00H,33H,33H,00H,00H ; : 0529 00 052A 00656600 =1 904 DB 00H,65H,66H,00H,00H ; ; 052E 00 052F 00081422 =1 905 DB 00H,08H,14H,22H,41H ; < 0533 41 0534 14141414 =1 906 DB 14H,14H,14H,14H,14H ; = 0538 14 0539 41221408 =1 907 DB 41H,22H,14H,08H,00H ; > 053D 00 053E 20404548 =1 908 DB 20H,40H,45H,48H,30H ; ? 0542 30 0543 26494F41 =1 909 DB 26H,49H,4FH,41H,3EH ; @ 0547 3E 0548 3F484848 =1 910 DB 3FH,48H,48H,48H,3FH ; A 054C 3F 054D 7F494949 =1 911 DB 7FH,49H,49H,49H,36H ; B 0551 36 0552 3E414141 =1 912 DB 3EH,41H,41H,41H,22H ; C 0556 22 0557 7F414122 =1 913 DB 7FH,41H,41H,22H,1CH ; D 055B 1C 055C 7F494949 =1 914 DB 7FH,49H,49H,49H,41H ; E 0560 41 0561 7F484848 =1 915 DB 7FH,48H,48H,48H,40H ; F 0565 40 0566 3E414949 =1 916 DB 3EH,41H,49H,49H,2FH ; G 056A 2F A51 MACRO ASSEMBLER RBDC 25/07/99 15:58:57 PAGE 16 056B 7F080808 =1 917 DB 7FH,08H,08H,08H,7FH ; H 056F 7F 0570 00417F41 =1 918 DB 00H,41H,7FH,41H,00H ; I 0574 00 0575 0201417E =1 919 DB 02H,01H,41H,7EH,40H ; J 0579 40 057A 7F081422 =1 920 DB 7FH,08H,14H,22H,41H ; K 057E 41 057F 7F010101 =1 921 DB 7FH,01H,01H,01H,01H ; L 0583 01 0584 7F201820 =1 922 DB 7FH,20H,18H,20H,7FH ; M 0588 7F 0589 7F100804 =1 923 DB 7FH,10H,08H,04H,7FH ; N 058D 7F 058E 3E414141 =1 924 DB 3EH,41H,41H,41H,3EH ; O 0592 3E 0593 7F484848 =1 925 DB 7FH,48H,48H,48H,30H ; P 0597 30 0598 3E414542 =1 926 DB 3EH,41H,45H,42H,3DH ; Q 059C 3D 059D 7F484C4A =1 927 DB 7FH,48H,4CH,4AH,31H ; R 05A1 31 05A2 31494949 =1 928 DB 31H,49H,49H,49H,46H ; S 05A6 46 05A7 40407F40 =1 929 DB 40H,40H,7FH,40H,40H ; T 05AB 40 05AC 7E010101 =1 930 DB 7EH,01H,01H,01H,7EH ; U 05B0 7E 05B1 7C020102 =1 931 DB 7CH,02H,01H,02H,7CH ; V 05B5 7C 05B6 7E010E01 =1 932 DB 7EH,01H,0EH,01H,7EH ; W 05BA 7E 05BB 63140814 =1 933 DB 63H,14H,08H,14H,63H ; X 05BF 63 05C0 70080708 =1 934 DB 70H,08H,07H,08H,70H ; Y 05C4 70 05C5 43454951 =1 935 DB 43H,45H,49H,51H,61H ; Z 05C9 61 05CA 007F4141 =1 936 DB 00H,7FH,41H,41H,00H ; [ 05CE 00 05CF 7F414141 =1 937 DB 7FH,41H,41H,41H,7FH ; [] 05D3 7F 05D4 0041417F =1 938 DB 00H,41H,41H,7FH,00H ; ] 05D8 00 05D9 10204020 =1 939 DB 10H,20H,40H,20H,10H ; ^ 05DD 10 05DE 01010101 =1 940 DB 01H,01H,01H,01H,01H ; _ 05E2 01 05E3 00402010 =1 941 DB 00H,40H,20H,10H,00H ; \ 05E7 00 05E8 02151515 =1 942 DB 02H,15H,15H,15H,0FH ; a 05EC 0F 05ED 7F091111 =1 943 DB 7FH,09H,11H,11H,0EH ; b 05F1 0E 05F2 0E111111 =1 944 DB 0EH,11H,11H,11H,02H ; c 05F6 02 05F7 0E111109 =1 945 DB 0EH,11H,11H,09H,7FH ; d 05FB 7F 05FC 0E151515 =1 946 DB 0EH,15H,15H,15H,0CH ; e 0600 0C 0601 083F4840 =1 947 DB 08H,3FH,48H,40H,20H ; f 0605 20 0606 18252525 =1 948 DB 18H,25H,25H,25H,3EH ; g 060A 3E 060B 7F081010 =1 949 DB 7FH,08H,10H,10H,0FH ; h 060F 0F A51 MACRO ASSEMBLER RBDC 25/07/99 15:58:57 PAGE 17 0610 00115F01 =1 950 DB 00H,11H,5FH,01H,00H ; i 0614 00 0615 0201115E =1 951 DB 02H,01H,11H,5EH,00H ; j 0619 00 061A 7F040A11 =1 952 DB 7FH,04H,0AH,11H,00H ; k 061E 00 061F 00417F01 =1 953 DB 00H,41H,7FH,01H,00H ; l 0623 00 0624 1F100C10 =1 954 DB 1FH,10H,0CH,10H,0FH ; m 0628 0F 0629 1F081010 =1 955 DB 1FH,08H,10H,10H,0FH ; n 062D 0F 062E 0E111111 =1 956 DB 0EH,11H,11H,11H,0EH ; o 0632 0E 0633 1F141414 =1 957 DB 1FH,14H,14H,14H,08H ; p 0637 08 0638 08141414 =1 958 DB 08H,14H,14H,14H,1FH ; q 063C 1F 063D 1F081010 =1 959 DB 1FH,08H,10H,10H,08H ; r 0641 08 0642 09151515 =1 960 DB 09H,15H,15H,15H,02H ; s 0646 02 0647 107E1101 =1 961 DB 10H,7EH,11H,01H,02h ; t 064B 02 064C 1E010101 =1 962 DB 1EH,01H,01H,01H,1FH ; u 0650 1F 0651 1C020102 =1 963 DB 1CH,02H,01H,02H,1CH ; v 0655 1C 0656 1E010601 =1 964 DB 1EH,01H,06H,01H,1EH ; w 065A 1E 065B 110A040A =1 965 DB 11H,0AH,04H,0AH,11H ; x 065F 11 0660 18050505 =1 966 DB 18H,05H,05H,05H,1EH ; y 0664 1E 0665 11131519 =1 967 DB 11H,13H,15H,19H,11H ; z 0669 11 066A 00083641 =1 968 DB 00H,08H,36H,41H,00H ; { 066E 00 066F 00007F00 =1 969 DB 00H,00H,7FH,00H,00H ; | 0673 00 0674 00413608 =1 970 DB 00H,41H,36H,08H,00H ; } 0678 00 0679 08082A1C =1 971 DB 08H,08H,2AH,1CH,08H ; -> 067D 08 067E 081C2A08 =1 972 DB 08H,1CH,2AH,08H,08H ; <- 0682 08 =1 973 =1 974 =1 975 976 $INCLUDE(Timer.A51) =1 977 ; This module services the real time interrupt =1 978 ; =1 979 ; Get a Real Time interrupt every One millisecond (using SOF interrupt) =1 980 ; =1 981 ; Strobe the Reader Board columns every 25msec so that no flicker is evident =1 982 ; The circuitry is shown in Figure 6-22 except that Port C is used not Port B =1 983 ; Pin assignment of Port C is: =1 984 ; Bit 0 = Clock =1 985 ; Bit 1 = Data =1 986 ; Bit 2 = Reset =1 987 ; Bit 3 = DIR/OE (0 = Write LEDs, 1 = Read Buttons) 0683 =1 988 ServiceTimerRoutine: 0683 D54A37 =1 989 DJNZ Msec_counter, Done ; Only need to react every 25msec 0686 754A19 =1 990 MOV Msec_counter, #25 ; Reinitialize =1 991 0689 =1 992 SetupPointers: A51 MACRO ASSEMBLER RBDC 25/07/99 15:58:57 PAGE 18 0689 7898 =1 993 MOV R0, #Low(PortC_OUT) ; Will strobe the hardware here 068B 7996 =1 994 MOV R1, #Low(PortA_OUT) ; Will output data to here 068D 7A01 =1 995 MOV R2, #0001 ; PortC, Code for Clock Hi =1 996 068F E548 =1 997 MOV A, DisplayPosition ; Which column are we currently displaying 0691 B4271A =1 998 CJNE A, #39, NextColumn 0694 =1 999 ReadButtons: ; Before each full scan 0694 907F9C =1 1000 MOV DPTR, #PortA_OE ; Need to flip Port A 0697 E4 =1 1001 CLR A 0698 F0 =1 1002 MOVX @DPTR, A ; Setup Port A for INPUT 0699 740C =1 1003 MOV A, #01100b ; Set DIR and Reset = 1 069B F2 =1 1004 MOVX @R0, A ; Enable hardware to input 069C 7999 =1 1005 MOV R1, #Low(PortA_Pins) 069E E3 =1 1006 MOVX A, @R1 ; Get Port A data and save for a later Report 069F F547 =1 1007 MOV ButtonsValue, A ; 06A1 7996 =1 1008 MOV R1, #Low(PortA_OUT) 06A3 7410 =1 1009 MOV A, #0010H ; Set DIR and Reset = 0 and Data = 1 06A5 F2 =1 1010 MOVX @R0, A 06A6 74FF =1 1011 MOV A, #0FFH 06A8 F0 =1 1012 MOVX @DPTR, A ; Setup Port A for OUTPUT 06A9 7A0B =1 1013 MOV R2, #0011 ; PortC, Code for Data and Clock = 1 06AB 7548FF =1 1014 MOV DisplayPosition, #-1 ; Allow for later INC 06AE =1 1015 NextColumn: 06AE E4 =1 1016 CLR A ; First clear display to prevent ghosting 06AF F3 =1 1017 MOVX @R1, A ; Write to Port A 06B0 EA =1 1018 MOV A, R2 ; = 00x1, x = Data = 1 on Column 0, else 0 06B1 F2 =1 1019 MOVX @R0, A ; Set clock HI to select next column 06B2 E4 =1 1020 CLR A ; Set Data and Clock Low 06B3 F2 =1 1021 MOVX @R0, A ; Complete strobe of hardware 06B4 0548 =1 1022 INC DisplayPosition ; Point to next row of dots 06B6 E548 =1 1023 MOV A, DisplayPosition 06B8 2449 =1 1024 ADD A, #LEDBuffer ; Index into LED Buffer 06BA F8 =1 1025 MOV R0, A 06BB E6 =1 1026 MOV A, @R0 ; Get the next row of dots 06BC F3 =1 1027 MOVX @R1, A ; Update the display 06BD 22 =1 1028 Done: Ret =1 1029 1030 1031 END A51 MACRO ASSEMBLER RBDC 25/07/99 15:58:57 PAGE 19 SYMBOL TABLE LISTING ------ ----- ------- N A M E T Y P E V A L U E ATTRIBUTES ACC. . . . . . . . . . . . . . . D ADDR 00E0H A B. . . . . . . . . . . . . . . . D ADDR 00F0H A BADREQUEST . . . . . . . . . . . C ADDR 01C6H A BUMPDPTR . . . . . . . . . . . . C ADDR 01CCH A BUTTONSVALUE . . . . . . . . . . D ADDR 0047H A CLEARDISPLAY . . . . . . . . . . C ADDR 03F5H A CLEARINT2. . . . . . . . . . . . C ADDR 0119H A COMMANDTABLE . . . . . . . . . . C ADDR 01FAH A CONFIGURATIONCOUNT . . . . . . . N NUMB 0002H A CONFIGURED . . . . . . . . . . . B ADDR 0020H.0 A COPYRB . . . . . . . . . . . . . C ADDR 01A0H A COPYSD . . . . . . . . . . . . . C ADDR 02D2H A CORRECTSUBROUTINE. . . . . . . . C ADDR 01D5H A CREATEINPUTREPORT. . . . . . . . C ADDR 048FH A CURRENTCONFIGURATION . . . . . . D ADDR 0046H A CURRENTPOSITION. . . . . . . . . D ADDR 0047H A DECONFIGURED . . . . . . . . . . C ADDR 0281H A DEVICEDESCRIPTOR . . . . . . . . C ADDR 02E0H A DEVICE_CLEAR_FEATURE . . . . . . C ADDR 023AH A DEVICE_GET_STATUS. . . . . . . . C ADDR 026BH A DEVICE_SET_FEATURE . . . . . . . C ADDR 023AH A DISPLAYPOSITION. . . . . . . . . D ADDR 0048H A DMLOOP . . . . . . . . . . . . . C ADDR 044EH A DONE . . . . . . . . . . . . . . C ADDR 06BDH A DOTCONFIGLENGTH. . . . . . . . . N NUMB 001BH A DOTCONFIGURATIONDESCRIPTOR . . . C ADDR 0333H A DOTHIDDESCRIPTOR . . . . . . . . C ADDR 0345H A DOTINTERFACEDESCRIPTOR . . . . . C ADDR 033CH A DOTMODE. . . . . . . . . . . . . C ADDR 0446H A DOTREPORTDESCRIPTOR. . . . . . . C ADDR 034EH A DOTREPORTLENGTH. . . . . . . . . N NUMB 0017H A DPH. . . . . . . . . . . . . . . D ADDR 0083H A DPL. . . . . . . . . . . . . . . D ADDR 0082H A DPS. . . . . . . . . . . . . . . D ADDR 0086H A EI . . . . . . . . . . . . . . . D ADDR 00A8H A EICON. . . . . . . . . . . . . . D ADDR 00D8H A EIE. . . . . . . . . . . . . . . D ADDR 00E8H A ENDOFDESCRIPTORS . . . . . . . . C ADDR 03D5H A ENDPOINT_CLEAR_FEATURE . . . . . C ADDR 023CH A ENDPOINT_GET_STATUS. . . . . . . C ADDR 026FH A ENDPOINT_SET_FEATURE . . . . . . C ADDR 023AH A ENDPOINT_SYNC_FRAME. . . . . . . C ADDR 023AH A EP0CONTROL . . . . . . . . . . . N NUMB 7FB4H A EP0INBUFFER. . . . . . . . . . . N NUMB 7F00H A EP0IN_ISR. . . . . . . . . . . . C ADDR 0118H A EP0OUTBUFFER . . . . . . . . . . N NUMB 7EC0H A EP0OUT_ISR . . . . . . . . . . . C ADDR 0118H A EP1INBUFFER. . . . . . . . . . . N NUMB 7E80H A EP1IN_ISR. . . . . . . . . . . . C ADDR 0118H A EP1OUT_ISR . . . . . . . . . . . C ADDR 0118H A EP2IN_ISR. . . . . . . . . . . . C ADDR 0118H A EP2OUT_ISR . . . . . . . . . . . C ADDR 0118H A EP3IN_ISR. . . . . . . . . . . . C ADDR 0118H A EP3OUT_ISR . . . . . . . . . . . C ADDR 0118H A EP4IN_ISR. . . . . . . . . . . . C ADDR 0118H A EP4OUT_ISR . . . . . . . . . . . C ADDR 0118H A EP5IN_ISR. . . . . . . . . . . . C ADDR 0118H A EP5OUT_ISR . . . . . . . . . . . C ADDR 0118H A EP6IN_ISR. . . . . . . . . . . . C ADDR 0118H A EP6OUT_ISR . . . . . . . . . . . C ADDR 0118H A A51 MACRO ASSEMBLER RBDC 25/07/99 15:58:57 PAGE 20 EP7IN_ISR. . . . . . . . . . . . C ADDR 0118H A EP7OUT_ISR . . . . . . . . . . . C ADDR 0118H A EXIF . . . . . . . . . . . . . . D ADDR 0091H A EXITISR. . . . . . . . . . . . . C ADDR 014BH A EXPIRED_TIME . . . . . . . . . . D ADDR 0042H A FIXUPTHENREPLY . . . . . . . . . C ADDR 02CCH A FLAGS. . . . . . . . . . . . . . D ADDR 0020H A GET_CLASS_DESCRIPTOR . . . . . . C ADDR 02AEH A GET_CONFIGURATION. . . . . . . . C ADDR 0264H A GET_DESCRIPTOR . . . . . . . . . C ADDR 0284H A GET_IDLE . . . . . . . . . . . . C ADDR 025DH A GET_INTERFACE. . . . . . . . . . C ADDR 023AH A GET_PROTOCOL . . . . . . . . . . C ADDR 023AH A GET_REPORT . . . . . . . . . . . C ADDR 0250H A HANDSHAKE. . . . . . . . . . . . C ADDR 01ADH A I2CCONTROL . . . . . . . . . . . N NUMB 7FA5H A I2CDATA. . . . . . . . . . . . . N NUMB 7FA6H A I2CDATABYTE. . . . . . . . . . . D ADDR 0047H A I2C_ISR. . . . . . . . . . . . . C ADDR 0118H A IDLE_TIME. . . . . . . . . . . . D ADDR 0041H A IN07IEN. . . . . . . . . . . . . N NUMB 7FACH A IN07IRQ. . . . . . . . . . . . . N NUMB 7FA9H A IN0BYTECOUNT . . . . . . . . . . N NUMB 7FB5H A IN1BYTECOUNT . . . . . . . . . . N NUMB 7FB7H A INITIALIZEINTERRUPTSYSTEM. . . . C ADDR 0413H A INITIALIZEIOSYSTEM . . . . . . . C ADDR 03F9H A INT0_ISR . . . . . . . . . . . . C ADDR 0118H A INT1_ISR . . . . . . . . . . . . C ADDR 0118H A INT4_ISR . . . . . . . . . . . . C ADDR 0118H A INT5_ISR . . . . . . . . . . . . C ADDR 0118H A INT6_ISR . . . . . . . . . . . . C ADDR 0118H A INTERFACE_CLEAR_FEATURE. . . . . C ADDR 023AH A INTERFACE_GET_STATUS . . . . . . C ADDR 026FH A INTERFACE_SET_FEATURE. . . . . . C ADDR 023AH A INVALID. . . . . . . . . . . . . C ADDR 023AH A IRLOOP . . . . . . . . . . . . . C ADDR 0496H A ISDESCRIPTOR . . . . . . . . . . B ADDR 0020H.3 A LEDBUFFER. . . . . . . . . . . . D ADDR 0049H A LEDSTROBE. . . . . . . . . . . . D ADDR 0048H A LEDVALUE . . . . . . . . . . . . D ADDR 0049H A LIGHTVALUES. . . . . . . . . . . D ADDR 0047H A LIMITVALUES. . . . . . . . . . . D ADDR 0047H A LOADSUDPTR . . . . . . . . . . . C ADDR 01B8H A LOOKUPTABLE. . . . . . . . . . . C ADDR 04A3H A LTCOPY . . . . . . . . . . . . . C ADDR 047FH A MAIN . . . . . . . . . . . . . . C ADDR 042BH A MONITORSPACE . . . . . . . . . . D ADDR 0021H A MORE . . . . . . . . . . . . . . C ADDR 0434H A MOTORCONTROL . . . . . . . . . . D ADDR 0048H A MSEC_COUNTER . . . . . . . . . . D ADDR 004AH A NEXTCOLUMN . . . . . . . . . . . C ADDR 06AEH A NEXTDPTR . . . . . . . . . . . . C ADDR 01CBH A NEXTSTRING . . . . . . . . . . . C ADDR 02A0H A NOTB5. . . . . . . . . . . . . . C ADDR 0181H A NOT_USED . . . . . . . . . . . . C ADDR 0118H A OLD_BUTTONS. . . . . . . . . . . D ADDR 0047H A ORLOOP . . . . . . . . . . . . . C ADDR 045DH A OTHER1 . . . . . . . . . . . . . C ADDR 0296H A OTHER2 . . . . . . . . . . . . . C ADDR 02BCH A OTHER3 . . . . . . . . . . . . . C ADDR 02C8H A OUT07IEN . . . . . . . . . . . . N NUMB 7FADH A OUT07IRQ . . . . . . . . . . . . N NUMB 7FAAH A OUT0BYTECOUNT. . . . . . . . . . N NUMB 7FC5H A OVERLAY. . . . . . . . . . . . . D ADDR 0047H A PAGEREG. . . . . . . . . . . . . D ADDR 0092H A PCON . . . . . . . . . . . . . . D ADDR 0087H A A51 MACRO ASSEMBLER RBDC 25/07/99 15:58:57 PAGE 21 PORTA_CONFIG . . . . . . . . . . N NUMB 7F93H A PORTA_OE . . . . . . . . . . . . N NUMB 7F9CH A PORTA_OUT. . . . . . . . . . . . N NUMB 7F96H A PORTA_PINS . . . . . . . . . . . N NUMB 7F99H A PORTB_CONFIG . . . . . . . . . . N NUMB 7F94H A PORTB_OE . . . . . . . . . . . . N NUMB 7F9DH A PORTB_OUT. . . . . . . . . . . . N NUMB 7F97H A PORTB_PINS . . . . . . . . . . . N NUMB 7F9AH A PORTC_CONFIG . . . . . . . . . . N NUMB 7F95H A PORTC_OE . . . . . . . . . . . . N NUMB 7F9EH A PORTC_OUT. . . . . . . . . . . . N NUMB 7F98H A PORTC_PINS . . . . . . . . . . . N NUMB 7F9BH A PROCESSOUTPUTREPORT. . . . . . . C ADDR 043FH A PSW. . . . . . . . . . . . . . . D ADDR 00D0H A READBUTTONS. . . . . . . . . . . C ADDR 0694H A READERBOARDWITHDUALCONFIGURATION N NUMB ----- REPLY. . . . . . . . . . . . . . C ADDR 023CH A REPLY2 . . . . . . . . . . . . . C ADDR 0283H A REPLYBUFFER. . . . . . . . . . . D ADDR 0043H A RESERVED . . . . . . . . . . . . C ADDR 0118H A RESET. . . . . . . . . . . . . . C ADDR 03D7H A SENDDATA . . . . . . . . . . . . B ADDR 0020H.2 A SENDEP0INBUFFER. . . . . . . . . C ADDR 01A9H A SERVICESETUPPACKET . . . . . . . C ADDR 0169H A SERVICETIMERROUTINE. . . . . . . C ADDR 0683H A SETEP0CONTROL. . . . . . . . . . C ADDR 01B0H A SETUPDAT . . . . . . . . . . . . N NUMB 7FE8H A SETUPPOINTERS. . . . . . . . . . C ADDR 0689H A SET_CLASS_DESCRIPTOR . . . . . . C ADDR 023AH A SET_CONFIGURATION. . . . . . . . C ADDR 0272H A SET_DESCRIPTOR . . . . . . . . . C ADDR 023AH A SET_IDLE . . . . . . . . . . . . C ADDR 0257H A SET_INTERFACE. . . . . . . . . . C ADDR 023AH A SET_PROTOCOL . . . . . . . . . . C ADDR 023AH A SET_REPORT . . . . . . . . . . . C ADDR 023DH A SKIP . . . . . . . . . . . . . . C ADDR 01D4H A SKIP1. . . . . . . . . . . . . . C ADDR 0463H A SKIP2. . . . . . . . . . . . . . C ADDR 046AH A SOF_ISR. . . . . . . . . . . . . C ADDR 0158H A SP . . . . . . . . . . . . . . . D ADDR 0081H A STALL. . . . . . . . . . . . . . B ADDR 0020H.1 A STARTXFER. . . . . . . . . . . . C ADDR 01ACH A STRING0. . . . . . . . . . . . . C ADDR 0365H A STRING1. . . . . . . . . . . . . C ADDR 0369H A STRING2. . . . . . . . . . . . . C ADDR 0395H A STRING3. . . . . . . . . . . . . C ADDR 03AFH A STRING4. . . . . . . . . . . . . C ADDR 03C3H A SUDAV_ISR. . . . . . . . . . . . C ADDR 013CH A SUDPTR . . . . . . . . . . . . . N NUMB 7FD4H A SUSPEND_ISR. . . . . . . . . . . C ADDR 0129H A SUTOK_ISR. . . . . . . . . . . . C ADDR 0118H A TEMP . . . . . . . . . . . . . . D ADDR 0040H A TEXTCONFIGLENGTH . . . . . . . . N NUMB 0022H A TEXTCONFIGURATIONDESCRIPTOR. . . C ADDR 02F2H A TEXTENDPOINTDESCRIPTOR . . . . . C ADDR 030DH A TEXTHIDDESCRIPTOR. . . . . . . . C ADDR 0304H A TEXTINTERFACEDESCRIPTOR. . . . . C ADDR 02FBH A TEXTMODE . . . . . . . . . . . . C ADDR 0453H A TEXTREPORTDESCRIPTOR . . . . . . C ADDR 0314H A TEXTREPORTLENGTH . . . . . . . . N NUMB 001FH A TIMER0_ISR . . . . . . . . . . . C ADDR 0118H A TIMER1_ISR . . . . . . . . . . . C ADDR 0118H A TIMER2_ISR . . . . . . . . . . . C ADDR 0118H A UART0_ISR. . . . . . . . . . . . C ADDR 0118H A UART1_ISR. . . . . . . . . . . . C ADDR 0118H A USBCONTROL . . . . . . . . . . . N NUMB 7FD6H A A51 MACRO ASSEMBLER RBDC 25/07/99 15:58:57 PAGE 22 USBIEN . . . . . . . . . . . . . N NUMB 7FAEH A USBIRQ . . . . . . . . . . . . . N NUMB 7FABH A USBRESET_ISR . . . . . . . . . . C ADDR 0120H A USB_ISR. . . . . . . . . . . . . C ADDR 0100H A WAIT100MSEC. . . . . . . . . . . C ADDR 042EH A WAIT1MSEC. . . . . . . . . . . . C ADDR 0431H A WAIT4D . . . . . . . . . . . . . C ADDR 0247H A WAKEUP_ISR . . . . . . . . . . . C ADDR 0139H A WITHINSAMEPAGE . . . . . . . . . N NUMB 00D2H A REGISTER BANK(S) USED: 0 ASSEMBLY COMPLETE. 0 WARNING(S), 0 ERROR(S)