	.module main

	;; this apparently does not work; the anchorchips controller
	;; sometimes gets into a state where it responds to get_device_descriptor
	;; requests with zero length descriptors
	
	;; define code segments link order
	.area CODE (CODE)

	;; -----------------------------------------------------

	;; special function registers (which are not predefined)
	dpl0    = 0x82
	dph0    = 0x83
	dpl1    = 0x84
	dph1    = 0x85
	dps     = 0x86
	ckcon   = 0x8E
	spc_fnc = 0x8F
	exif    = 0x91
	mpage   = 0x92
	scon0   = 0x98
	sbuf0   = 0x99
	scon1   = 0xC0
	sbuf1   = 0xC1
	eicon   = 0xD8
	eie     = 0xE8
	eip     = 0xF8

	;; anchor xdata registers
	IN0BUF		= 0x7F00
	OUT0BUF		= 0x7EC0
	IN1BUF		= 0x7E80
	OUT1BUF		= 0x7E40
	IN2BUF		= 0x7E00
	OUT2BUF		= 0x7DC0
	IN3BUF		= 0x7D80
	OUT3BUF		= 0x7D40
	IN4BUF		= 0x7D00
	OUT4BUF		= 0x7CC0
	IN5BUF		= 0x7C80
	OUT5BUF		= 0x7C40
	IN6BUF		= 0x7C00
	OUT6BUF		= 0x7BC0
	IN7BUF		= 0x7B80
	OUT7BUF		= 0x7B40
	SETUPBUF	= 0x7FE8
	SETUPDAT	= 0x7FE8

	EP0CS		= 0x7FB4
	IN0BC		= 0x7FB5
	IN1CS		= 0x7FB6
	IN1BC		= 0x7FB7
	IN2CS		= 0x7FB8
	IN2BC		= 0x7FB9
	IN3CS		= 0x7FBA
	IN3BC		= 0x7FBB
	IN4CS		= 0x7FBC
	IN4BC		= 0x7FBD
	IN5CS		= 0x7FBE
	IN5BC		= 0x7FBF
	IN6CS		= 0x7FC0
	IN6BC		= 0x7FC1
	IN7CS		= 0x7FC2
	IN7BC		= 0x7FC3
	OUT0BC		= 0x7FC5
	OUT1CS		= 0x7FC6
	OUT1BC		= 0x7FC7
	OUT2CS		= 0x7FC8
	OUT2BC		= 0x7FC9
	OUT3CS		= 0x7FCA
	OUT3BC		= 0x7FCB
	OUT4CS		= 0x7FCC
	OUT4BC		= 0x7FCD
	OUT5CS		= 0x7FCE
	OUT5BC		= 0x7FCF
	OUT6CS		= 0x7FD0
	OUT6BC		= 0x7FD1
	OUT7CS		= 0x7FD2
	OUT7BC		= 0x7FD3

	IVEC		= 0x7FA8
	IN07IRQ		= 0x7FA9
	OUT07IRQ	= 0x7FAA
	USBIRQ		= 0x7FAB
	IN07IEN		= 0x7FAC
	OUT07IEN	= 0x7FAD
	USBIEN		= 0x7FAE
	USBBAV		= 0x7FAF
	BPADDRH		= 0x7FB2
	BPADDRL		= 0x7FB3

	SUDPTRH		= 0x7FD4
	SUDPTRL		= 0x7FD5
	USBCS		= 0x7FD6
	TOGCTL		= 0x7FD7
	USBFRAMEL	= 0x7FD8
	USBFRAMEH	= 0x7FD9
	FNADDR		= 0x7FDB
	USBPAIR		= 0x7FDD
	IN07VAL		= 0x7FDE
	OUT07VAL	= 0x7FDF
	AUTOPTRH	= 0x7FE3
	AUTOPTRL	= 0x7FE4
	AUTODATA	= 0x7FE5

	;; isochronous endpoints. only available if ISODISAB=0

	OUT8DATA	= 0x7F60
	OUT9DATA	= 0x7F61
	OUT10DATA	= 0x7F62
	OUT11DATA	= 0x7F63
	OUT12DATA	= 0x7F64
	OUT13DATA	= 0x7F65
	OUT14DATA	= 0x7F66
	OUT15DATA	= 0x7F67

	IN8DATA		= 0x7F68
	IN9DATA		= 0x7F69
	IN10DATA	= 0x7F6A
	IN11DATA	= 0x7F6B
	IN12DATA	= 0x7F6C
	IN13DATA	= 0x7F6D
	IN14DATA	= 0x7F6E
	IN15DATA	= 0x7F6F

	OUT8BCH		= 0x7F70
	OUT8BCL		= 0x7F71
	OUT9BCH		= 0x7F72
	OUT9BCL		= 0x7F73
	OUT10BCH	= 0x7F74
	OUT10BCL	= 0x7F75
	OUT11BCH	= 0x7F76
	OUT11BCL	= 0x7F77
	OUT12BCH	= 0x7F78
	OUT12BCL	= 0x7F79
	OUT13BCH	= 0x7F7A
	OUT13BCL	= 0x7F7B
	OUT14BCH	= 0x7F7C
	OUT14BCL	= 0x7F7D
	OUT15BCH	= 0x7F7E
	OUT15BCL	= 0x7F7F

	OUT8ADDR	= 0x7FF0
	OUT9ADDR	= 0x7FF1
	OUT10ADDR	= 0x7FF2
	OUT11ADDR	= 0x7FF3
	OUT12ADDR	= 0x7FF4
	OUT13ADDR	= 0x7FF5
	OUT14ADDR	= 0x7FF6
	OUT15ADDR	= 0x7FF7
	IN8ADDR		= 0x7FF8
	IN9ADDR		= 0x7FF9
	IN10ADDR	= 0x7FFA
	IN11ADDR	= 0x7FFB
	IN12ADDR	= 0x7FFC
	IN13ADDR	= 0x7FFD
	IN14ADDR	= 0x7FFE
	IN15ADDR	= 0x7FFF

	ISOERR		= 0x7FA0
	ISOCTL		= 0x7FA1
	ZBCOUNT		= 0x7FA2
	INISOVAL	= 0x7FE0
	OUTISOVAL	= 0x7FE1
	FASTXFR		= 0x7FE2

	;; CPU control registers

	CPUCS		= 0x7F92

	;; IO port control registers

	PORTACFG	= 0x7F93
	PORTBCFG	= 0x7F94
	PORTCCFG	= 0x7F95
	OUTA		= 0x7F96
	OUTB		= 0x7F97
	OUTC		= 0x7F98
	PINSA		= 0x7F99
	PINSB		= 0x7F9A
	PINSC		= 0x7F9B
	OEA		= 0x7F9C
	OEB		= 0x7F9D
	OEC		= 0x7F9E

	;; I2C controller registers

	I2CS		= 0x7FA5
	I2DAT		= 0x7FA6

	;; -----------------------------------------------------

	.area CODE (CODE)
	mov	sp,#0x7f
	clr	a
	mov	psw,a
	mov	dps,a

	;; some indirect register setup
	mov	ckcon,#0x31	; one external wait state, to avoid chip bugs
	;; disable interrupts
	mov	ie,a		; disable timer 0 int
	mov	eie,a		; disable USB interrupts
	mov	dptr,#USBIEN
	movx	@dptr,a
	mov	dptr,#IN07IEN
	movx	@dptr,a
	mov	dptr,#OUT07IEN
	movx	@dptr,a
	;; allow Windows time to finish the writecpucs control transfer
	;; 10ms delay loop
	mov	dptr,#-6000
3$:	inc	dptr		; 3 cycles
	mov	a,dpl0		; 2 cycles
	orl	a,dph0		; 2 cycles
	jnz	3$		; 3 cycles
	;; disconnect from USB bus
	mov	dptr,#USBCS
	clr	a
	movx	@dptr,a
	;; init USB subsystem
	mov	dptr,#ISOCTL
	mov	a,#1		; disable ISO endpoints
	movx	@dptr,a
	mov	dptr,#USBBAV
	mov	a,#1		; enable autovector, disable breakpoint logic
	movx	@dptr,a
	clr	a
	mov	dptr,#INISOVAL
	movx	@dptr,a
	mov	dptr,#OUTISOVAL
	movx	@dptr,a
	mov	dptr,#USBPAIR
	movx	@dptr,a
	mov	dptr,#IN07VAL
	movx	@dptr,a
	mov	dptr,#OUT07VAL
	movx	@dptr,a
	;; USB:	clear endpoint toggles
	mov	dptr,#TOGCTL
	mov	r7,#7		; clear endpoint toggles 1-7
10$:	mov	a,r7
	orl	a,#0x10
	movx	@dptr,a
	orl	a,#0x30
	movx	@dptr,a		; clear EP r7 in toggle
	mov	a,r7
	movx	@dptr,a
	orl	a,#0x20
	movx	@dptr,a		; clear EP r7 out toggle
	djnz	r7,10$
	;; configure IO ports
	mov	dptr,#PORTACFG
	mov	a,#0
	movx	@dptr,a
	mov	dptr,#OUTA
	mov	a,#0x80		; set PROG lo
	movx	@dptr,a
	mov	dptr,#OEA
	mov	a,#0xc2		; out: TMS,TDI,PROG  in: DONE
	movx	@dptr,a
	mov	dptr,#PORTBCFG
	mov	a,#0
	movx	@dptr,a
	mov	dptr,#OEB
	mov	a,#0
	movx	@dptr,a
	mov	dptr,#PORTCCFG
	mov	a,#0
	movx	@dptr,a
	mov	dptr,#OUTC
	mov	a,#0x08
	movx	@dptr,a
	mov	dptr,#OEC
	mov	a,#0x2e		; out: LEDCON,LEDSTA,TCK,INIT  in: TDO
	movx	@dptr,a
	;; wait 1 sec
	mov	r2,#100
	;; 10ms delay loop
0$:	mov	dptr,#-6000
1$:	inc	dptr		; 3 cycles
	mov	a,dpl0		; 2 cycles
	orl	a,dph0		; 2 cycles
	jnz	1$		; 3 cycles
	djnz	r2,0$
	;; reconnect to USB bus
	mov	dptr,#USBCS
	mov	a,#4
	movx	@dptr,a
	;; light green led
	mov	dptr,#OUTC
	mov	a,#0x20
	movx	@dptr,a

        .if 0
        ;; light green led
        mov     dptr,#OUTC
        mov     a,#0x20
        movx    @dptr,a
100$:   sjmp    100$
        .else
        ;; light green led
100$:   mov     dptr,#OUTC
        mov     a,#0x20
        movx    @dptr,a
        ;; wait 400ms
        mov     r2,#40
        ;; 10ms delay loop
101$:   mov     dptr,#(-6000)&0xffff
102$:   inc     dptr            ; 3 cycles
        mov     a,dpl0          ; 2 cycles
        orl     a,dph0          ; 2 cycles
        jnz     102$            ; 3 cycles
        djnz    r2,101$
        ;; switch green led off
        mov     dptr,#OUTC
        mov     a,#0x28
        movx    @dptr,a
        ;; wait 100ms
        mov     r2,#10
        ;; 10ms delay loop
103$:   mov     dptr,#(-6000)&0xffff
104$:   inc     dptr            ; 3 cycles
        mov     a,dpl0          ; 2 cycles
        orl     a,dph0          ; 2 cycles
        jnz     104$            ; 3 cycles
        djnz    r2,103$
        sjmp    100$
        .endif
        
	.area	OSEG (OVR,DATA)
	.area	BSEG (BIT)
	.area	ISEG (DATA)
	.area	DSEG (DATA)
	.area	XSEG (DATA)
