Some 8051 code to program and erase an AMD 28Fxx flash rom.
Paul Stoffregen, paul@ece.orst.edu  http://www.ece.orst.edu/~paul/

;where the flash rom is located in memory
.equ	bmem, 0x1000	;not currently used
.equ	emem, 0xFFFF
.equ	bflash, 0x8000	;need to know where to erase
.equ	eflash, 0xFFFF

;timing parameters for AMD Flash ROM 28F256
;.equ	 pgmwait, 10	;22.1184 MHz crystal assumed
.equ	pgmwait, 19	;11.0592 MHz
.equ	verwait, 5
;.equ	 erwait1, 40	;fourty delays @22.1184
.equ	erwait1, 20	;twenty delays for 11.0592 MHz
.equ	erwait2, 229	;each delay .5 ms @22.1184MHz

;note, all reads with MOVC, all writes with MOVX.


;routine that erases the whole flash rom!

;note: modify so it restores interrupts to original state, not
;necessarily to all on.

erall:	
	mov	dptr, #bflash		;first program to all 00's
erall1: clr	a
	movc	a, @a+dptr
	jz	erall2			;don't waste time!
	clr	a
	lcall	prgm			;ok, program this byte
erall2: inc	dptr
	mov	a, #(eflash+1)&255
	cjne	a, dpl, erall1
	mov	a, #((eflash+1)>>8)&255
	cjne	a, dph, erall1		;after this it's all 00's
	mov	dptr, #bflash		;beginning address
	mov	r4, #232		;max # of trials, lsb
	mov	r5, #4			;max # of trials, msb-1
erall3: 
	djnz	r4, erall3a
	djnz	r5, erall3a
	setb	c
	ret				;if it didn't work!
erall3a:mov	a, #20h
	clr	ea		 ;-	;turn off all interrupts!!
	movx	@dptr, a		;send the erase setup
	movx	@dptr, a		;and begin the erase
	mov	r3, #erwait1
erwt:	mov	r2, #erwait2		;now wait 10ms...
	djnz	r2, *
	djnz	r3, erwt
erall4: mov	a, #0A0h
	movx	@dptr, a		;send erase verify
	mov	r2, verwait		;wait for 6us
	djnz	r2, *
	clr	a
	movc	a, @a+dptr
	setb	ea		 ;-	;turn interrupts back on
	cpl	a
	jnz	erall3			;erase again if not FF
	inc	dptr
	mov	a, #((eflash+1)>>8)&255 ;verify whole array
	cjne	a, dph, erall4
	mov	a, #(eflash+1)&255
	cjne	a, dpl, erall4
	mov	a, #255
	mov	dptr, #bflash
	movx	@dptr, a		;reset the flash rom
	clr	a
	movx	@dptr, a		;and go back to read mode
	clr	c
	ret


;a routine that writes ACC to into flash memory at DPTR
; assumes that Vpp is active and stable already.
; C is set if error occurs, C is clear if it worked
prgm:	mov	b, a
	mov	r2, #25  	;try to program 25 times if needed
prgm2:	mov	a, #40h
	clr	ea	    ;-	;turn off all interrupts!!
	movx	@dptr, a	;send setup programming command
	mov	a, b
	movx	@dptr, a	;write to the cell
	mov	r3, #pgmwait	;now wait for 10us
	djnz	r3, *
	mov	a, #0xC0
	movx	@dptr, a	;send program verify command
	mov	r3, #verwait	;wait 6us while it adds margin
	djnz	r3, *
	clr	a
	movc	a, @a+dptr
	setb	ea	    ;-	;turn interrupts back on
	clr	c
	subb	a, b
	jz	prgmok		;note, C is still clear is ACC=0
	djnz	r2, prgm2
prgmbad:setb	c		;it gets here if programming failure
prgmok: clr	a
	movx	@dptr, a	;and go back into read mode
	mov	a, b		;restore ACC to original value
	ret
