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

📄 ps2code.asm

📁 PIC 系列单片机开发用于与计算机PS2通信的程序
💻 ASM
字号:
;---------------------------------------------------------------------------------------------
;       HEADER:
;---------------------------------------------------------------------------------------------
		TITLE       "PS/2 Keyboard Emulator"
		SUBTITLE    "Copyright 2001, Adam Chapweske"
		LIST	    P=16F877
		INCLUDE	    "p16f877.inc"
                RADIX       DEC
		ERRORLEVEL  -224, 1
                __CONFIG    _CP_OFF & _WDT_OFF & _XT_OSC

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

#DEFINE	DATA	PORTA, 2	;May be assigned to any I/O pin
#DEFINE	CLOCK	PORTA, 3	;May be assigned to any I/O pin

#DEFINE KEY	PORTB, 0


#DEFINE	PERIOD	20		;Time between reading of inputs.  Min=(osc frequency)/204800

;---------------------------------------------------------------------------------------------
;	RAM ALLOCATION:
;---------------------------------------------------------------------------------------------

  cblock 0x20

	TEMP0 ,TEMP1
	RECEIVE, PARITY, COUNTER	;Used in I/O routines
	OLDKEYCODE,NEWKEYCODE
  endc


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

  cblock 0x30		;Contains to-be-sent packet and last packet sent
	LENGTH
	SEND1
	SEND2
	SEND3
  endc

;---------------------------------------------------------------------------------------------
;       MACROS:
;---------------------------------------------------------------------------------------------

;Delay "Cycles" instruction cycles
Delay		macro	Time
  if (Time==1)
		nop
  		exitm
  endif
  if (Time==2)
		goto	$ + 1
		exitm
  endif
  if (Time==3)
		nop
		goto	$ + 1
		exitm
  endif
  if (Time==4)
		goto	$ + 1
		goto	$ + 1
		exitm
  endif
  if (Time==5)
		goto	$ + 1
		goto	$ + 1
		nop
		exitm
  endif
  if (Time==6)
		goto	$ + 1
		goto	$ + 1
		goto	$ + 1
		exitm
  endif
  if (Time==7)
		goto	$ + 1
		goto	$ + 1
		goto	$ + 1
		nop
		exitm
  endif
  if (Time%4==0)
		movlw	(Time-4)/4
		call	Delay_us
		exitm
  endif
  if (Time%4==1)
		movlw	(Time-5)/4
		call	Delay_us
		nop
		exitm
  endif
  if (Time%4==2)
		movlw	(Time-6)/4
		call	Delay_us
		goto	$ + 1
		exitm
  endif
  if (Time%4==3)
		movlw	(Time-7)/4
		call	Delay_us
		goto	$ + 1
		nop
		exitm
  endif
		endm
;---------------------------------------------------------------------------------------------
;       ORG 0x000:
;---------------------------------------------------------------------------------------------

		org	0x000
		goto	Start
;---------------------------------------------------------------------------------------------
;	EMULATE BAT:
;---------------------------------------------------------------------------------------------
BATdelay	clrf	TEMP0		;Used for a 400 ms delay at power-on
		clrf	TEMP1
DelayLoop	Delay	6
		decfsz	TEMP0, f
		goto	DelayLoop
		decfsz	TEMP1, f
		goto	DelayLoop
		retlw	0x00

;---------------------------------------------------------------------------------------------
;	HANDLE COMMAND:
;---------------------------------------------------------------------------------------------

  if (high Table1End != 0)
		ERROR	"Command handler table must be in low memory page"
  endif

Command		movlw	0xED		;0xE6 is lowest code
		subwf	RECEIVE, w
		bnc	MainLoop
HandlerTable	addwf	PCL, f		;Add offset
		goto	MainLoop	;0xED
		goto	KeyBd_EE	;0xEE
		goto	MainLoop	;0xEF
		goto	MainLoop	;0xF0
		goto	MainLoop	;0xF1
		goto	MainLoop	;0xF2
		goto	MainLoop	;0xF3
		goto	KeyBd_F4	;0xF4
		goto	MainLoop	;0xF5
		goto	MainLoop	;0xF6
		goto	MainLoop	;0xF7
		goto	MainLoop	;0xF8
		goto	MainLoop	;0xF9
		goto	MainLoop	;0xFA
		goto	MainLoop	;0xFB
		goto	MainLoop	;0xFC
		goto	MainLoop	;0xFD
		goto	PacketOut	;0xFE - Resend
Table1End	goto	Reset		;0xFF - Reset


;---------------------------------------------------------------------------------------------
;	START:
;---------------------------------------------------------------------------------------------

Start		clrf	PORTA
		clrf	PORTB
		bsf	STATUS, RP0	;(TRISA=TRISB=0xFF by default)

		movlw	0x57		;Timer mode, assign max. prescaler, enable pullups
		movwf	OPTION_REG
		movlw   0x07
		movwf	ADCON1
		clrf	PORTC
		bcf	STATUS, RP0
		goto 	Reset

;---------------------------------------------------------------------------------------------
;       Reset Mode:
;---------------------------------------------------------------------------------------------
Reset		clrf	PORTC
		movlw	0x00
		movwf	OLDKEYCODE
		movwf	NEWKEYCODE
		movlw	0xAA
		movwf	SEND1		;Load BAT completion code
		movlw	0x01
		movwf	LENGTH
		call	BATdelay
		bcf	STATUS,RP0		
		goto	PacketOut	;Output 2-byte "completion-code, device ID" packet

;---------------------------------------------------------------------------------------------
;       Stream/Remote Mode:
;---------------------------------------------------------------------------------------------
MainLoop	btfss	DATA
		goto 	PacketIn
		bsf	PORTC,2
		call 	ReadInputs
		movf 	OLDKEYCODE, w
		xorwf 	NEWKEYCODE ,w
		btfsc	STATUS, Z
		goto 	MainLoop
		goto 	Report


;---------------------------------------------------------------------------------------------
;	REPORT:
;---------------------------------------------------------------------------------------------

Report		bsf	PORTC,0
		movf 	OLDKEYCODE,w
		andlw 	0xff
		btfss 	STATUS,Z
		goto 	KeyBreak
		goto 	KeyMake
KeyBreak	movlw 	0xf0
		movwf	SEND1
		movf 	OLDKEYCODE,w
		call 	Label
		movwf	SEND2
		movlw	0x02		;Movement data report length
		movwf	LENGTH
		movlw 	0x00
		movwf 	OLDKEYCODE
		goto 	PacketOut
KeyMake		movf 	NEWKEYCODE,w
		andlw 	0xff
		btfsc 	STATUS,Z
		goto	MainLoop
		movf 	NEWKEYCODE,w
		call 	Label
		movwf	SEND1
		movlw	0x01		;Movement data report length
		movwf	LENGTH
		movf 	NEWKEYCODE,w
		movwf 	OLDKEYCODE
		goto 	PacketOut

Label		addwf	PCL
		retlw	0x45
		retlw	0x46

;---------------------------------------------------------------------------------------------
;	OUTPUT PACKET
;---------------------------------------------------------------------------------------------

PacketOut	movlw	SEND1		;First byte of packet
		movwf	FSR
		movf	LENGTH, w	;Length of packet
		movwf	TEMP1
PacketOutLoop	movf	INDF, w		;Get data byte
		call	ByteOut		;  Output that byte
		xorlw	0xFF		;Test for RTS error
		bz	PacketIn
		xorlw	0xFE ^ 0xFF	;Test for inhibit error
		bz	PacketOut
		incf	FSR, f		;Point to next byte
		decfsz	TEMP1, f
		goto	PacketOutLoop
		goto	MainLoop

;---------------------------------------------------------------------------------------------
;	READ PACKET
;---------------------------------------------------------------------------------------------

PacketIn	
		call	ByteIn
		xorlw	0xFF		;Test for parity/framing error
		bz	KeyBd_ERR
		xorlw	0xFE ^ 0xFF	;Test for inhibit error
		bz	MainLoop
		movlw	0xFE		;Test for "Resend" command
		xorwf	RECEIVE, w
		bz	PacketOut
		movlw	0xEE
		xorwf	RECEIVE,w
		btfss	STATUS,Z
		goto	Acknowledge
		movlw	0xEE
		call	ByteOut
		goto	MainLoop
Acknowledge	movlw	0xFA		;Acknowledge
		call	ByteOut
		goto	Command
;---------------------------------------------------------------------------------------------
;	READ INPUTS:
;---------------------------------------------------------------------------------------------

ReadInputs	movlw  0x00
		btfsc  KEY
		movlw  0x01
		movwf  NEWKEYCODE
		return

;---------------------------------------------------------------------------------------------
;	HANDLE COMMANDS:
;---------------------------------------------------------------------------------------------


;Invalid command
KeyBd_ERR	movlw	0xFE
		call	ByteOut
		bsf	PORTC,1
		goto	MainLoop

KeyBd_EE	movlw	0xEE
		call	ByteOut
		goto	MainLoop

KeyBd_F2	movlw	0xAB
		movwf	SEND1
		movlw	0x83
		movwf	SEND2
		movlw	0x02
		movwf	LENGTH
		goto	PacketOut

KeyBd_F4	goto	MainLoop		

;---------------------------------------------------------------------------------------------
;	OUTPUT ONE BYTE:  - TIMING IS CRITICAL!!!
;---------------------------------------------------------------------------------------------

ByteOut		movwf	TEMP0
InhibitLoop	btfss	CLOCK		;Test for inhibit
		goto	InhibitLoop
		Delay	100		;(50 microsec = 58 clock cycles, min)
		btfss	CLOCK
		goto	InhibitLoop
		btfss	DATA		;Check for request-to-send
		retlw	0xFF
		clrf	PARITY
		movlw	0x08
		movwf	COUNTER
		movlw	0x00
		call	BitOut		;Start bit (0)
		btfss	CLOCK		;Test for inhibit
		goto	ByteOutEnd
		Delay	4
ByteOutLoop	movf	TEMP0, w
		xorwf	PARITY, f
		call	BitOut		;Data bits
		btfss	CLOCK		;Test for inhibit
		goto	ByteOutEnd
		rrf	TEMP0, f
		decfsz	COUNTER, f
		goto	ByteOutLoop
		Delay	2
		comf	PARITY, w
		call	BitOut		;Parity bit
		btfss	CLOCK		;Test for inhibit
		goto	ByteOutEnd
		Delay	5
		movlw	0xFF
		call	BitOut		;Stop bit (1)
		Delay	48
		retlw	0x00
ByteOutEnd	bsf	STATUS, RP0
		bsf	DATA
		bsf	CLOCK
		bcf	STATUS, RP0
		retlw	0xFE

BitOut		bsf	STATUS, RP0
		andlw	0x01
		btfss	STATUS, Z
		bsf	DATA
		btfsc	STATUS, Z
		bcf	DATA
		Delay	21
		bcf	CLOCK
		Delay	45
		bsf	CLOCK
		bcf	STATUS, RP0
		Delay	5
		return

;---------------------------------------------------------------------------------------------
;	READ ONE BYTE: (Takes about 1ms) - TIMING IS CRITICAL!!!
;---------------------------------------------------------------------------------------------

ByteIn		btfss	CLOCK		;Test for Request-to-send
		retlw	0xFE
		btfsc	DATA
		retlw	0xFE
		movlw	0x08
		movwf	COUNTER
		clrf	PARITY
		Delay	28
ByteInLoop	call	BitIn		;Data bits
		btfss	CLOCK		;Test for inhibit
		retlw	0xFE
		bcf	STATUS, C
		rrf	RECEIVE, f
		iorwf	RECEIVE, f
		xorwf	PARITY,f
		decfsz	COUNTER, f
		goto	ByteInLoop
		Delay	1
		call	BitIn		;Parity bit
		btfss	CLOCK		;Test for inhibit
		retlw	0xFE
		xorwf	PARITY, f
		Delay	5
ByteInLoop1	Delay	1
		call	BitIn		;Stop bit
		btfss	CLOCK		;Test for inhibit
		retlw	0xFE
		xorlw	0x00
		btfsc	STATUS, Z
		clrf	PARITY
		btfsc	STATUS, Z	;Stop bit = 1?
		goto	ByteInLoop1	;  No--keep clocking.

		bsf	STATUS, RP0	;Acknowledge
		bcf	DATA
		Delay	11
		bcf	CLOCK
		Delay	45
		bsf	CLOCK
		Delay	7
		bsf	DATA
		bcf	STATUS, RP0

		btfss	PARITY, 7	;Parity correct?
		retlw	0xFF		;  No--return error

		Delay	45
		retlw	0x00

BitIn		Delay	8
		bsf	STATUS, RP0
		bcf	CLOCK
		Delay	45
		bsf	CLOCK
		bcf	STATUS, RP0
		Delay	21
		btfsc	DATA
		retlw	0x80
		retlw	0x00

;---------------------------------------------------------------------------------------------
;	DELAY:
;---------------------------------------------------------------------------------------------
;Delays 4w+4 cycles (including call,return, and movlw) (0=256)
Delay_us	addlw	-1  		;Precise delays used in I/O
		btfss	STATUS, Z
		goto	Delay_us
		return

		end

⌨️ 快捷键说明

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