; 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

	MOV	CurrentConfiguration, A	; This example supports two configurations

	MOV	R0, #DisplayPosition    ; Note LEDBuffer follows DisplayPosition

	MOV	R7, #43

	MOV	A, #8			; Display a horizontal line

ClearDisplay:

	MOV	@R0, A

	INC	R0

	DJNZ	R7, ClearDisplay

			

InitializeIOSystem:			; This example uses PortA an IN/OUT and 

					; the lower 4 bits of PortC as OUT

; Assume a pre-existing configuration (ie Dscope)	

	MOV	R0, #LOW(PortA_Config)	; PageReg = 7F = HIGH(PortA_Config)

	CLR	A

	MOVX	@R0, A			; No alternate functions

	MOV	R1, #LOW(PortA_OE)

	CPL	A			; = 0FFH

	MOVX	@R1, A			; Enable PortA for Output

	MOV	R0, #LOW(PortC_Config)	; PageReg = 7F = HIGH(PortC_Config)

	MOV	R1, #LOW(PortC_OE)

	MOVX	A, @R0			; Get current configuration

	ANL	A, #0F0H

	MOVX	@R0, A			; No alternate functions on lower nibble

	MOVX	A, @R1			; Get current configuration

	ORL	A, #0FH

	MOVX	@R1, A			; Enable PortC_Bits[3:0] for Output

	MOV	R0, #LOW(PortC_Out)

	MOVX	A, @R0

	ANL	A, #0F0H

	MOVX	@R0, A			; Set Bits [3:0] low



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

; See comment re SetConfiguration in DTables.A51

	MOV	DPTR, #EP0OutBuffer

	MOVX	A, @DPTR



; The interpretation of the Report is different depending upon the MODE we are in

;	MOV	A, CurrentConfiguration

	CJNE	A, #2, TextMode



DOTmode:

; The report is 41 bytes long and is a mode byte then a buffer

	MOV	DPTR, #EP0OutBuffer+1	; Point to the Report (after Mode Byte)

	MOV	R0, #LEDBuffer

	MOVX	A, @DPTR

	MOV	R7, #40			; Have room for 40 Columns

DMLoop:	MOVX	A, @DPTR                ; Update the local buffer

        MOV	@R0, A

	DJNZ	R7, DMloop

	RET



TextMode:

; The report is 7 characters long and must be translated into a dot pattern

	MOV	DPS, #1			; Select the other Data Pointer

	MOV	DPTR, #EP0OutBuffer+1	; 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 "other" DPTR

	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	; <-