もう古いPICなので、新規に買うなら16F887の方が断然安くてお得。
 5個ほど手持ちがあるので、とりあえずブートローダー込みで使えるようにしておこうと思ったら、ウェブ上でちゃんとしたモノが見つからなかったので、asmちょっといじってみた。
TinyBootloader for 16F877A(zip)
	radix DEC
	LIST      P=16F877A, F=INHX8M	; change also: Configure->SelectDevice from Mplab
xtal EQU 20000000					; you may also want to change: _HS_OSC _XT_OSC
baud EQU 115200						; standard TinyBld baud rates: 115200 or 19200
	; The above 3 lines can be changed and buid a bootloader for the desired frequency (and PIC type)

	;********************************************************************
	;	Tiny Bootloader		16FxxxA series		Size=100words
	;	claudiu.chiculita@ugal.ro
	;	http://www.etc.ugal.ro/cchiculita/software/picbootloader.htm
	;
	;	this modified for 16F877A
	;
	;	if you use CCS-C compiler,
	;	#build(reset=0x1, interrupt=0x5)
	;	#org 0x1F90, 0x1FFF {}
	;********************************************************************

	#include "../icdpictypes.inc"
	#include "../spbrgselect.inc"
	#include "../bankswitch.inc"
	#define first_address max_flash-100 ; 100 word in size

	__CONFIG  _HS_OSC & _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _LVP_OFF & _DEBUG_OFF

	errorlevel 1, -305			; suppress warning msg that takes f as default

	
	cblock 0x20
	buffer:80
	endc
	
	cblock 0x78
	crc
	contor
	i
	cnt1
	cnt2
	cnt3
	flag
	endc
	

SendL macro car
	movlw	car
	movwf	TXREG
	endm

;0000000000000000000000000 RESET 00000000000000000000000000

		ORG     0x0000
		PAGESEL IntrareBootloader
		GOTO    IntrareBootloader

;&&&&&&&&&&&&&&&&&&&&&&&   START     &&&&&&&&&&&&&&&&&
;----------------------  Bootloader  ----------------------
;               
;PC_flash:	C1h			AddrH  AddrL  nr  ...(DataLo DataHi)...  crc
;PIC_response:   id   K                                                 K

	
	ORG first_address
	nop
	nop
	nop
	nop
	org first_address+4
IntrareBootloader
			;init serial port
	clrf	STATUS
	bsf		STATUS,RP0			; BANK1_
	movlw	b'00100100'
	movwf	TXSTA
	movlw	spbrg_value
	movwf	SPBRG
	BANK0_
	movlw	b'10010000'
	movwf	RCSTA
			;wait for computer
	call	Receive			
	sublw	0xC1				; Expect C1
	skpz
	goto	way_to_exit
	SendL IdTypePIC				; PIC type
	;SendL IdSoftVer			; firmware ver x
MainLoop
	clrf	STATUS				; bank0
	SendL 'K'
mainl
	clrf	crc
	call	Receive				; H
		bsf STATUS,RP1			; bank2
	movwf	EEADRH
	movwf	flag				; used to detect if is eeprom
	call	Receive				; L
	bsf STATUS,RP1				; bank2
	movwf	EEADR




	call	Receive				; count
	movwf	contor
	movwf	i
	incf	i
	movlw	buffer-1
	movwf	FSR
rcvoct
	call	Receive
	incf	FSR
	movwf	INDF
	decfsz	i
	goto	rcvoct
	
	movf	crc,f				; check checksum
	skpz
	goto	ziieroare
				;write
		bsf STATUS,RP1			; bank switch 0->2
	movlw	buffer
	movwf	FSR
writeloop						; write 2 bytes = 1 instruction
	clrwdt
	movf	INDF,w
	movwf	EEDATA
	incf	FSR
	movf	INDF,w
	movwf	EEDATH
	incf	FSR	
		BANK3_					; bank  2->3
	bcf		EECON1,EEPGD
	btfss	flag,6				; is eeprom (or flash)
	bsf		EECON1,EEPGD
	bsf		EECON1,WREN
	movlw	0x55
	movwf	EECON2
	movlw	0xaa
	movwf	EECON2	
	bsf		EECON1,WR
	nop
	nop
waitwre	
;	btfsc	EECON1,WR			; for eeprom writes (wait to finish write)
;	goto	waitwre
	bcf		EECON1,WREN
		BANK2_					; bank2
	incf	EEADR				; does not cross zones
	btfss	flag,6				; if writing to EEPROM, skip first counter dec.
	decf	contor
	decfsz	contor
	goto	writeloop
	
	goto	MainLoop
ziieroare
	SendL 'N'
	goto	mainl
	  

Receive
	clrf	STATUS
	movlw	xtal/2000000+1		; for 20MHz => 11 => 1second
	movwf	cnt1
rpt2						
	clrf	cnt2
rpt3
	clrf	cnt3
rptc
		btfss PIR1,RCIF			; test RX
		goto $+4
		movf RCREG,w			; return in W
		addwf crc,f				; compute checksum
		return
	clrwdt
	decfsz	cnt3
	goto	rptc
	decfsz	cnt2
	goto	rpt3
	decfsz	cnt1
	goto	rpt2
								; timeout:
way_to_exit						; exit in all other cases; must be BANK0/1
								; BANK0_
	bcf	RCSTA,	SPEN			; deactivate UART
	goto	first_address
;*************************************************************
; After reset
; Do not expect the memory to be zero,
; Do not expect registers to be initialised like in catalog.

			END