⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usb2lpt2.a51

📁 无线网络课件,是一份非常好的讲述无线通信领域的资料.
💻 A51
📖 第 1 页 / 共 2 页
字号:
	sjmp	eri_Auto
eri_nBootRom:
	clr	ACC.0		;Hier: Schreibadresse!
	mov	I2C_Addr,a
	LDX	NEXT		;wIndexH
	anl	a,#0Fh		;Low-Nibble
	mov	I2C_ALen,a	;黚ernehmen, wie es ist
	LDX			;noch einmal wIndexH
	swap	a
	anl	a,#0Fh		;High-Nibble
	jnz	eri_nAuto
eri_Auto:			;bei HINIBBLE(wIndexH)=0 Paginierung automatisch
	mov	a,I2C_Addr
	anl	a,#0F0h
	xrl	a,#0A0h		;Irgendein serieller EEPROM-Typ (Axh)?
	jnz	eri_e		;nein, keine (automatische) Paginierung
	mov	a,I2C_ALen
	cjne	a,#1,eri_n1	;Adress-L鋘ge 1? (Und kein NoStop/NoStart?)
	mov	a,#EPAGE8-1	;Maske setzen
	sjmp	eri_s
eri_n1:	cjne	a,#2,eri_e	;Adress-L鋘ge 2? Alles andere: ohne Auto-Paging!
	mov	a,#EPAGE16-1	;Maske setzen
	sjmp	eri_s
eri_nAuto:
	mov	r0,a		;Bitmaske erzeugen: 1->00, 2->01, 3->03
	clr	a		;4->07, 5->0F, 6->1F, 7->3F, 8->7F, 9->FF
	sjmp	eri_f
eri_l:	setb	c
	rlc	a		;nach links schieben, Einsen einf黦en
eri_f:	djnz	r0,eri_l
eri_s:	mov	I2C_PMask,a
	setb	I2C_Paging	;Auto-Paging aktivieren
	setb	I2C_Verify	;Verify aktivieren (vorerst gemeinsam)
eri_e:	RETNC			;(wom鰃lich sp鋞er auch beim Lesen, wenn erf.)

;=============================
;== EEPROM- und RAM-Zugriff ==
;=============================
MemR:	LODS		;lesen (Zweiter Autopointer versagt
	STX1		;sowieso wegen Bug im FX2!!)
	djnz	r4,MemR
	ret
MemW:	LDX1
	STOS		;schreiben
	djnz	r4,MemW
	ret
	
Partial_64:
;Subtrahiert 64 (bzw. R4) von der Gesamtl鋘ge; R7=0 wenn letzter Block
	mov	r4,#64
Partial_r4:
	mov	a,r6
	subb	a,r4
	jnc	pa1
	clr	c
	djnz	r7,pa1	;Letzte "Runde" mit R7=0
	LD	r4,a,r6
	inc	r4
	ret
pa1:	mov	r6,a
	ret
	
LongEP0:
;Diese Routine funktioniert "absichtlich" nicht bei L鋘gen >=FF00h,
;Control-Transfers sind ohnehin auf 1000h (4KB) beschr鋘kt.
;Behandlung aller "langen" EP0-Transfers, mit selbstmodifizierendem Code
;dptr=Zeiger Leseroutine (R1=AutoPtr-EP0Buf, DPTR=wValue, R4=L鋘ge)
;R7:R6=Zeiger Schreibroutine (dito, f黵 OUT-Transfers)
;Alle diese Routinen bekommen DPTR=wValue, R4=Transferl鋘ge, R1=AutoDat,
;und d黵fen R6, R7 nicht ver鋘dern. (R7=0 f黵 letzten Teiltransfer)
;F0 ist (zun鋍hst) gel鰏cht
;R4=bmRequestType
	clr	F0
	mov	a,DPH0
	mov	r5,DPL0	;retten
	mov	dptr,#PatchR+1
	STORX
	mov	a,r5
	STORX	NEXT
	mov	a,r7
	mov	dptr,#PatchW+1
	STORX			;High-Teil
	mov	a,r6
	STORX	NEXT		;Low-Teil
	LDX	SetupDat+2	;wValueL
	mov	DPL0,a
	LDX	NEXT		;SetupDat+3
	mov	DPH0,a
	LDX	SetupDat+6	;wLengthL
	add	a,#0FFh
	mov	r6,a
	LDX	NEXT		;wLengthH
	addc	a,#0		;erh鰄en f黵 Funktion von Partial_xx
	mov	r7,a
	cjne	r4,#01000000b,a3_no	;bmRequestType
	jz	LEP0E		;Keine Daten!
LEP0W:	WAIT_EP0_OUT
	mov	r4,a
	call	Partial_R4
	MOVW	AutoPtr1,Out0Buf
	mov	r1,#LOW(XAutoDat1)
PatchW:	lcall	0
	jc	LEP0E
	mov	a,r7
	jnz	LEP0W		;n鋍hste Runde, sowie CY=0
	ret
	
a3_no:	cjne	r4,#11000000b,err2	;bmRequestType
	jz	LEP0E
LEP0R:	call	Partial_64
	WAIT_EP0_IN
	push	AR4		;retten f黵 In0BC
	 MOVW	AutoPtr1,In0Buf
	 mov	r1,#LOW(XAutoDat1)
PatchR:	 lcall	0
	pop	ACC
	jc	LEP0E
	STX	In0BC
	mov	a,r7
	jnz	LEP0R		;n鋍hste Runde, sowie CY=0
LEP0E:	ret
err2:	RETC

;=========================
;== Routinen f黵 Ende 0 ==	;PE: R0=SetupDat, R4=SDAT[0], R5=SDAT[2]
;=========================	                  R6=SDAT[4], R7=SDAT[5]
IF MyID
 ClassOut	equ	00100001b	;Klassenrequest (Drucker)
 ClassIn	equ	10100001b
ELSE
 ClassOut	equ	01000000b	;VendorRequest zum Test im EzMr
 ClassIn	equ	11000000b
ENDIF
;CountString: String Nr. R5-1 aus Descriptor-Liste ausw鋒len
;PE: DPTR=String-Beschreiber-Liste (gerade Adresse!)
;    DPS=0 (sonst geht's nicht!)
;    R5=String-Nummer+1
;PA: CY=1 wenn String-Liste "vorfristig" zu Ende
;    DPTR=String-Beschreiber (stets gerade Adresse)
;VR: dptr,r5,a
cs_l:	LOADX
	jz	cs_ep0stall
	add	a,dpl0
	mov	dpl0,a
	jnc	CountString
	 inc	dph0
CountString:
	djnz	r5,cs_l
	RETNC
cs_ep0stall:	RETC

ep_cs:
;Rechnet Endpoint-ID in INxCS/OUTxCS-Adresse um
;PE: R6=[SetupDat+4]=Enden-Adresse
;PA: R0=Zeiger auf EPxCS (Low-Teil)
;VR: A,R0,C
	mov	a,r6
	;Zehn m鰃liche F鋖le:	 01 81 02 82 04 84 06 86 08 88
	cjne	a,#1,ep_cs1	;01
	mov	a,#0FFh		;FF
	sjmp	ep_cs2
ep_cs1:	rr	a		;   40 01 41 02 42 03 43 04 44
	anl	a,#7		;   00 01 01 02 02 03 03 04 04
ep_cs2:	add	a,#LOW(EP1InCS)
	mov	r0,a
	ret
ResTog:	;Togglebit von R6=Endpoint r點ksetzen
	mov	a,r6
	mov	c,ACC.7
	mov	ACC.4,c
	anl	a,#1Fh
ResTo:	STX	TOGCTL		;Toggle-Bit adressieren
	setb	ACC.5
	STX			;Togglebit zur點ksetzen
	ret
ResTogAll:	;Alle Togglebits r點ksetzen, VR: R5
	mov	r5,#1Fh
ResTo0:	mov	a,r5
	call	ResTo		;alle au遝r EP0Out (der geht immer)
	djnz	r5,ResTo0
	ret

GetStatus:
	cjne	r4,#ClassIn,gs_nid	;GET_DEVICE_ID? (Nur Interface 1)
;hier: GetDeviceId
	;cjne	r7,#1,err1	;Interface, muss 1 sein
	ajmp	GetDeviceId
	;sjmp	nullin		;zwei Nullen senden, zurzeit kein String
gs_nid:
	cjne	r4,#80h,gs_no_dev	;GS_DEVICE
nullin:	clr	a		;kein WakeUp(Bit1), kein SelfPower(Bit0)
wordin:	STORX	In0Buf
	STORX	NEXT,0
	STX	In0BC,2
	ret
gs_no_dev:
	cjne	r4,#81h,gs_no_if	;GS_INTERFACE
	jmp	nullin		;auch zwei Nullen melden
gs_no_if:
	cjne	r4,#82h,err1	;GS_ENDPOINT
	call	ep_cs
	LDX			;STALL-Bit angeln
	anl	a,#1
	jmp	wordin

ClearFeature:	;numerisch gleich: GetPortStatus
	cjne	r4,#ClassIn,cf_nps	;Klassenrequest
;hier: GetPortStatus
	;cjne	r6,#1,err1	;nur Interface 1
	acall	in1
	anl	a,#00111000b
	ajmp	OneByteIn	;Info-Byte senden
cf_nps:
	cjne	r4,#2,err1
	cjne	r5,#0,err1	;einziges Feature: STALL
	call	ep_cs		;Endpoint zur Control+Status-Adresse umrechnen
	STX	,0		;STALL entfernen
	jmp	ResTog

SoftReset:
	cjne	r4,#ClassOut,err1
	;cjne	r6,#1,err1	;nur Interface 1
	clr	IOA.INI		;RESET-Impuls ausgeben
	LDX	GpifIdleCtl
	anl	a,#70h
	orl	a,#011b		;SEL=L, AF=H, STB=H
	STX
	setb	IOA.INI
	ret

SetFeature:
	cjne	r4,#2,err1	;FT_ENDPOINT
	cjne	r5,#0,err1	;einziges Feature: STALL
	call	ep_cs		;Endpoint zur Control+Status-Adresse umrechnen
	STX	,1		;STALL setzen
	ret
err1:	RETC

GetDescriptor:
	cjne	r4,#80h,err1	;nur DEVICE_IN
	LDX	SetupDat+3		;wValueH
	cjne	a,#01h,gd_no_dev	;GD_DEVICE
	mov	dptr,#DeviceDescriptor
gd_sto:	mov	a,DPH0
	STX	SudPtrH
	mov	a,DPL0
	STX	NEXT
	ret
gd_no_dev:
	cjne	a,#02h,gd_no_conf	;GD_CONFIGURATION
	orl	c,HighSpeed
gd_cd:	mov	dptr,#ConfigDescFS
	jnc	gd_sto
	mov	dptr,#ConfigDescHS
	clr	c
	jmp	gd_sto
gd_no_conf:
	cjne	a,#03h,gd_no_str	;GD_STRING
	mov	dptr,#StringDesc
	inc	r5
	call	CountString
	jc	err1
	jmp	gd_sto
gd_no_str:
	cjne	a,#06h,gd_no_qual	;GD_QUALIFIER
	mov	dptr,#DeviceQualifier
	jmp	gd_sto
gd_no_qual:
	cjne	a,#07h,err1		;GD_OTHERSPEED
	orl	c,/HighSpeed
	jmp	gd_cd

GetConfiguration:
	cjne	r4,#80h,err1		;nur DEVICE_IN
	mov	a,Configuration	 ;Entweder konfiguriert oder unkonfiguriert
OneByteIn:	
	STORX	In0Buf
	STX	In0BC,1
	ret

SetConfiguration:
	cjne	r4,#0,err1		;nur DEVICE_OUT
	mov	a,r5
	add	a,#-2
	jc	err1			;nur Konfiguration 0 oder 1
	mov	Configuration,r5
	ret

GetAltSet:
	cjne	r4,#81h,err1		;nur INTERFACE IN
	cjne	r6,#1,as_n1
	mov	a,AltSetting1
	jmp	OneByteIn
as_n1:	jnc	err1		;wenn Interface > 1
	clr	c
	clr	a
	jmp	OneByteIn

SetAltSet:
	cjne	r4,#1,err1		;nur INTERFACE OUT
;	cjne	r6,#0,as_n0	;Interface 0: h#s Parallelport
;	ret
as_n0:
	cjne	r6,#1,ep0s2	;Interface 1: USB-Druckerunterst黷zung
	mov	a,r5
	add	a,#-3
	jc	ep0s2		;Nur Alternative 0, 1 oder 2 zulassen
	mov	AltSetting1,r5
;	STX	OutPktEnd,84h	;EP4 (doppelt gepuffert) scharfmachen
;	STX
sude:	ret

SUD_Tab:
	ajmp	GetStatus	;0 - auch: GET_DEVICE_ID
	ajmp	ClearFeature	;1 - auch: GET_PORT_STATUS
	ajmp	SoftReset	;2 (normalerweise err1)
	ajmp	SetFeature	;3
ep0s2:	RETC			;4
	RETC	;SetAddress	;5, sollte nicht vorkommen
	ajmp	GetDescriptor	;6
	RETC	;SetDescriptor	;7
	ajmp	GetConfiguration;8
	ajmp	SetConfiguration;9
	ajmp	GetAltSet	;10
	ajmp	SetAltSet	;11
	;RETC	;SyncFrame	;12

HandleSUD:			;liefert CY=1 f黵 err1
	LDX	SetupDat+0	;bmRequestType -> R4
	mov	r4,a
	LDX	NEXT		;SetupDat+1: bRequest -> A
	cjne	a,#0A2h,hs1	;EEPROM-Zugriff?
	call	EReqInit	;wIndex heranziehen
	mov	dptr,#ERead
	MOVR	r6,r7,EE_W
	jmp	LongEP0
hs1:	cjne	a,#0A3h,hs2	;XRAM-Zugriff?
	mov	dptr,#MemR
	MOVR	r6,r7,MemW
	jmp	LongEP0
hs2:	mov	r7,a
	add	a,#-12		;nur 0..11 zulassen
	jc	ep0s2
	LDX	NEXT		;SetupDat+2: wValueL -> R5
	mov	r5,a
	LDX	SetupDat+4	;wIndexL -> R6
	mov	r6,a
	LDX	NEXT		;SetupDat+5: wIndexH ->
	xch	a,r7
	call	usr31		;darf bei CY=1 kein Register 鋘dern!
	jnc	sude		;bei CY=0 ist's des Users Eigenverantwortung
	JMPTBL	SUD_Tab

;==============================
;== Routinen f黵 Druckerport ==
;==============================
SetECR:	;ECR-Byte setzen, FIFOs leeren
	anl	a,#0F8h
	orl	a,#5		;FIFO leer setzen
	mov	ECR,a
	swap	a
	rr	a
	anl	a,#7
	inc	a
	mov	r3,a
	clr	a
	setb	c
se1:	rlc	a
	djnz	r3,se1		;Bit draus machen, testet sich besser
	mov	ECR_Bits,a

	mov	c,ECR_Bits.4	;EPP-Bit
	mov	a,#0FFh
	subb	a,#0
	mov	EppTimeout,a	;beim Einschalten von EPP auf Null, sonst 1

	mov	a,ECR_Bits
	anl	a,#00000101b	;Bei SPP oder SPP-FIFO auf Ausgabe schalten!
	jz	se3		;kein Schalten am Richtungsbit!
	clr	direction
	acall	DirChanged	;Ausgabetreiber stets aktiv - je nach OC-Simul.
se3:	mov	fifor,#Fifo
	mov	fifow,#Fifo
	ret

;===SPP-FIFO===========================
;Die Emulation der SPP-FIFO-Betriebsart
;Ein "echtes" Parallelport legt stets den FIFO-Kopf aufs Datenport...
SppXfer:
	jb	fifoe,exf	;wenn FIFO leer ist nichts zu tun
	LDX	GpifReadyStat
	jb	ACC.BSY,exf	;wenn besch鋐tigt dann geht's nicht
	mov	r0,fifor
	mov	OutB,@r0	;Datenbyte anlegen, Treiber muss aktiv sein
	LDX	GpifIdleCtl
	clr	ACC.STB
	STX			;Strobe aktivieren
	acall	IncFifoR	;Lesezeiger erh鰄en (und Zeit verbrauchen)
	LDX	GpifIdleCtl
	setb	ACC.STB
	STX			;Strobe zur點knehmen
exf:	ret

;===EPP===========================

;A auf IdleCtl ausgeben und max. 10 祍 auf WAIT=H warten
;PE: R0=LOW(GpifIdleCtl), A=GpifIdleCtl-Byte, R3=ASTB/DSTB-Maske
;PA: EppTimeOut.0, A=abgetastete Portpins
;VR: R0=LOW(GpifReadyStat),R1=A,R3
wait_epp:
	LDX	GpifIdleCtl
	mov	r1,a		;retten
	anl	a,r3		;ASTROBE/DSTROBE (ggf. WRITE)low
	STX
	mov	a,r3
	rrc	a		;Bit0 (Strobe = WRITE) extrahieren
	jc	sw0
	push	OEB		;bei Schreibzugriff: Zustand retten,...
	mov	OEB,#0FFh	;tempor鋜 alles Ausgabe
sw0:	;max. 10 祍 warten bis WAIT=H
	mov	r3,#15		;15 Runden 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -