Main.A51
; This module initializes the microcontroller then executes MAIN forever
;

Reset:
	MOV	SP, #235		; Initialize the Stack at top of internal memory
	MOV	PageReg, #7FH		; Needed to use MOVX @Ri

	MOV	R0, #LOW(USBControl)	; Simulate a disconnect
	MOVX	A, @R0
	ANL	A, #11110011b		; Clear DISCON, DISCOE
	MOVX	@R0, A
	CALL	Wait100msec   		; Give the host time to react
	MOVX	A, @R0			; Reconnect with this new identity
	ORL	A, #00000110b           ; Set DISCOE to enable pullup resistor
	MOVX	@R0, A	 		; Set RENUM so that 8051 handles USB requests
	CLR	A
	MOV	FLAGS, A		; Start in Default state
InitializeIOSystem:			; This example uses only I2C signals
					; No initialization is required
InitializeInterruptSystem:		; First initialize the USB level
	MOV	R0, #LOW(IN07IEN)
	MOVX	@R0, A			; Disable interrupts from IN Endpoints 0-7
	INC	R0
	MOVX	@R0, A			; Disable interrupts from OUT Endpoints 0-7
	INC	R0
	MOV	A, #00000011b
	MOVX	@R0, A			; Enable (Resume, Suspend,) SOF and SUDAV INTs
	INC	R0
	MOV	A, #00000001b
	MOVX	@R0, A	     		; Enable Auto Vectoring for USB interrupts
	MOV	R0, #LOW(OUT07IRQ)
	MOV	A, #0FFH
	MOVX	@R0, A			; Clear out any pending interrupts
	                                ; Now enable the main level
	MOV	EIE, #00000001b		; Enable INT2 = USB Interrupt (only) 		
        MOV	EI, #11000000b		; Enable interrupt subsystem (and Ser1 for Dscope)
 
; Initialization Complete.
; 
MAIN:
	NOP				; Not much of a main loop for this example
	JMP	MAIN			; All actions are initiated by interrupts
; We are a slave, we wait to be told what to do

Wait100msec:
	MOV	Temp, #100
Wait1msec:				; A delay loop
	MOV	DPTR, #-1200		
More:	INC	DPTR			; 3 cycles
	MOV	A, DPL                  ; + 2
	ORL	A, DPH                  ; + 2
	JNZ	More                    ; + 3 = 10 cycles x 1200 = 1msec
	DJNZ	Temp, Wait1msec
	RET

ProcessOutputReport:		  	; A Report has just been received
; The report is 40 bytes long
	MOV	DPS, #1			; Select the other Data Pointer
	MOV	DPTR, #EP0OutBuffer	; Point to the Report
	MOV	R0, #LEDBuffer
	MOV	R7, #7			; Have room for 7 characters
ORLoop:	MOVX	A, @DPTR
	JNB	ACC.7, Skip1		; Valid Characters are 20H to 7FH
	MOV	A, #3FH			; Replace characters > 7FH with ?
Skip1:	CLR	C
	SUBB	A, #20H
	JNC	Skip2
	MOV	A, #3CH			; Replace characters < 20H with []
Skip2:	MOV	B, #5
	MUL	AB			; B = HI((Char-20H)*5), A = LOW
	INC	DPS			; Swap to DPTR0
	MOV	DPTR, #LookupTable
	ADD	A, DPL
	MOV	DPL, A
	MOV	A, B
	ADDC	A, DPH
	MOV	DPH, A			; DPTR now pointing into Lookup Table
	MOV	R6, #5
LTCopy:	MOVX	A, @DPTR
	MOV	@R0, A
	INC	DPTR
	INC	R0
	DJNZ	R6, LTCopy
	MOV	@R0, #0			; Put a space between characters
	INC	R0
	INC	DPS			; Switch to DPTR1
	INC	DPTR			; Point to next character in Output Report 
	DJNZ	R7, ORLoop
	INC	DPS			; Return DPTR to DPTR0
					; Fall into CreateInputReport
CreateInputReport:
; The report is 40 bytes long in this example
; It contains the LED Buffer 
	MOV	DPTR, #EP1InBuffer	; Point to the buffer
	MOV	R0, #LEDBuffer
	MOV	R7, #40
IRLoop:	MOV	A, @R0
	MOVX	@DPTR, A
	INC	DPTR
	INC	R0
	DJNZ	R7, IRLoop 
	MOV	DPTR, #IN1ByteCount
	MOV	A, #40
	MOVX	@DPTR, A		; Endpoint 1 now 'armed', next IN will get data
	RET

LookupTable:				; Contains the 5 columns of the 7x5 display
	DB	00H,00H,00H,00H,00H	; SPACE
	DB	00H,00H,7DH,00H,00H	; !
	DB	00H,70H,00H,70H,00H	; "
	DB	14H,7FH,14H,7FH,14H	; #
	DB	12H,2AH,7FH,2AH,24H	; $
	DB	62H,64H,08H,13H,23H	; %
	DB	36H,49H,55H,22H,05H	; &
	DB	00H,50H,60H,00H,00H	; '
	DB	00H,1CH,22H,41H,00H	; (
	DB	00H,41H,22H,1CH,00H	; )
	DB	14H,08H,3EH,08H,14H	; *
	DB	08H,08H,3EH,08H,08H	; +
	DB	00H,05H,06H,00H,00H	; ,
	DB	08H,08H,08H,08H,08H	; -
	DB	00H,03H,03H,00H,00H	; .
	DB	02H,04H,08H,10H,20H	; /
	DB	3EH,45H,49H,51H,3EH	; 0
	DB	00H,21H,7FH,01H,00H	; 1
	DB	21H,43H,45H,49H,31H	; 2
	DB	42H,41H,51H,69H,46H	; 3
	DB	0CH,14H,24H,7FH,04H	; 4
	DB	72H,51H,51H,51H,4EH	; 5
	DB	1EH,29H,49H,49H,06H	; 6
	DB	40H,47H,48H,50H,60H	; 7
	DB	36H,49H,49H,49H,36H	; 8
	DB	30H,49H,49H,4AH,3CH	; 9
	DB	00H,33H,33H,00H,00H	; :
	DB	00H,65H,66H,00H,00H	; ;
	DB	00H,08H,14H,22H,41H	; <
	DB	14H,14H,14H,14H,14H	; =
	DB	41H,22H,14H,08H,00H	; >
	DB	20H,40H,45H,48H,30H	; ?
	DB	26H,49H,4FH,41H,3EH	; @
	DB	3FH,48H,48H,48H,3FH	; A
	DB	7FH,49H,49H,49H,36H	; B
	DB	3EH,41H,41H,41H,22H	; C
	DB	7FH,41H,41H,22H,1CH	; D
	DB	7FH,49H,49H,49H,41H	; E
	DB	7FH,48H,48H,48H,40H	; F
        DB	3EH,41H,49H,49H,2FH	; G
	DB	7FH,08H,08H,08H,7FH	; H
	DB	00H,41H,7FH,41H,00H	; I
	DB	02H,01H,41H,7EH,40H	; J
	DB	7FH,08H,14H,22H,41H	; K
	DB	7FH,01H,01H,01H,01H	; L
	DB	7FH,20H,18H,20H,7FH	; M
	DB	7FH,10H,08H,04H,7FH	; N
	DB	3EH,41H,41H,41H,3EH	; O
	DB	7FH,48H,48H,48H,30H	; P
	DB	3EH,41H,45H,42H,3DH	; Q
	DB	7FH,48H,4CH,4AH,31H	; R
	DB	31H,49H,49H,49H,46H	; S
	DB	40H,40H,7FH,40H,40H	; T
	DB	7EH,01H,01H,01H,7EH	; U
	DB	7CH,02H,01H,02H,7CH	; V
	DB	7EH,01H,0EH,01H,7EH	; W
	DB	63H,14H,08H,14H,63H	; X
	DB	70H,08H,07H,08H,70H	; Y
	DB	43H,45H,49H,51H,61H	; Z
	DB	00H,7FH,41H,41H,00H	; [
	DB	7FH,41H,41H,41H,7FH	; []
	DB	00H,41H,41H,7FH,00H	; ]
	DB	10H,20H,40H,20H,10H	; ^
	DB	01H,01H,01H,01H,01H	; _
	DB	00H,40H,20H,10H,00H	; \
	DB	02H,15H,15H,15H,0FH	; a
	DB	7FH,09H,11H,11H,0EH	; b
	DB	0EH,11H,11H,11H,02H	; c
	DB	0EH,11H,11H,09H,7FH	; d
	DB	0EH,15H,15H,15H,0CH	; e
	DB	08H,3FH,48H,40H,20H	; f
	DB	18H,25H,25H,25H,3EH	; g
	DB	7FH,08H,10H,10H,0FH	; h
	DB	00H,11H,5FH,01H,00H	; i
	DB	02H,01H,11H,5EH,00H	; j
	DB	7FH,04H,0AH,11H,00H	; k
	DB	00H,41H,7FH,01H,00H	; l
	DB	1FH,10H,0CH,10H,0FH	; m
	DB	1FH,08H,10H,10H,0FH	; n
	DB	0EH,11H,11H,11H,0EH	; o
	DB	1FH,14H,14H,14H,08H	; p
	DB	08H,14H,14H,14H,1FH	; q
	DB	1FH,08H,10H,10H,08H	; r
	DB	09H,15H,15H,15H,02H	; s
	DB	10H,7EH,11H,01H,02h	; t
	DB	1EH,01H,01H,01H,1FH	; u
	DB	1CH,02H,01H,02H,1CH	; v
	DB	1EH,01H,06H,01H,1EH	; w
	DB	11H,0AH,04H,0AH,11H	; x
	DB	18H,05H,05H,05H,1EH	; y
	DB	11H,13H,15H,19H,11H	; z
	DB	00H,08H,36H,41H,00H	; {
	DB	00H,00H,7FH,00H,00H	; |
	DB	00H,41H,36H,08H,00H	; }
	DB	08H,08H,2AH,1CH,08H	; ->
	DB	08H,1CH,2AH,08H,08H	; <-