; Attempt to erase an 8k block of the 39F512 Flash ROM
; chip on the 8051 development board, from
; http://www.pjrc.com/tech/8051/board3/board_image.html

; This code is in the the public domain. It is distributed in
; the hope that it will be useful, but without any warranty;
; without even the implied warranty of merchantability or fitness
; for a particular purpose.



.equ	locat, 0xF400	;Location for this program


.equ    cin, 0x0032       ;get byte from uart
.equ	phex, 0x0034
.equ    pstr, 0x0038      ;print string @dptr
.equ	newline, 0x0048
.equ	erblock, 0x0067	  ;PAULMON2 v2.1 req'd

.org    locat
.db     0xA5,0xE5,0xE0,0xA5     ;signiture
.db     35,255,0,0              ;id (35=normal prog)
.db     0,0,0,0                 ;prompt code vector
.dB     0,0,0,0                 ;reserved
.db     0,0,0,0                 ;reserved
.db     0,0,0,0                 ;reserved
.db     0,0,0,0                 ;user defined
.db     255,255,255,255         ;length and checksum (255=unused)
.db     "Erase 4k Flash Block",0
.org    locat+64          ;executable code begins here

erblk:	mov     dptr, #mesg1
	lcall	pstr
	lcall	cin
	add	a, #207
	jnc	er_no
	add	a, #248
	jc	er_no
	add	a, #16
	swap	a
	mov	r4, a		;r4 has MSB of block to erase
	sjmp	er_doit

er_no:	mov	dptr, #mesg_ab
	lcall	pstr
        ret

	;here's the code that actually attempts to erase
	;a block of the flash rom, without harming the
	;other three blocks.  This code should be able to
	;run from the flash (assuming that it's not
	;erasing its own block), since it does all the
	;dirty work by calling paulmon2 routines... so
	;that we won't be fetching instructions from the
	;flash while it's busy doing the erase.  This code
	;is specific to the 8051 development board, with
	;it's unusual address bus mapping
	; r4 has the high byte of the block to erase
er_doit:
	mov	dptr, #mesg_do
	lcall	pstr

;Flash:  D7  D6  D5  D4  D3  D2  D1  D0
;8051:   D6  D4  D5  D2  D7  D0  D1  D3
;
;0x30    0   0   1   1   0   0   0   0
;0xE2    0   0   1   0   0   1   0   0


	mov	dph, r4
	mov	dpl, #0
	mov	a, #0x24
	lcall	erblock

	;well, that should have done the erase... now the
	;big question is if it worked?

	mov	a, r4
	mov	dph, a
	add	a, #16
	mov	b, a
	mov	dpl, #0
chk:	clr	a
	movc	a, @a+dptr
	cpl	a
	jnz	bad
	inc	dptr
	mov	a, dpl
	jnz	chk
	mov	a, dph
	cjne	a, b, chk
good:
	mov	dptr, #mesg_ok
	lcall	pstr
	sjmp	done
bad:
	mov	dptr, #mesg_er
	lcall	pstr
done:
	mov	dptr, #mesgany
	lcall	pstr
	lcall	cin
	ret





mesg1:	.db	"Please choose block to erase", 13, 10
	.db	"  1)  0x8000 to 0x8FFF", 13, 10
	.db	"  2)  0x9000 to 0x9FFF", 13, 10
	.db	"  3)  0xA000 to 0xAFFF", 13, 10
	.db	"  4)  0xB000 to 0xBFFF", 13, 10
	.db	"  5)  0xC000 to 0xCFFF", 13, 10
	.db	"  6)  0xD000 to 0xDFFF", 13, 10
	.db	"  7)  0xE000 to 0xEFFF", 13, 10
	.db	"  8)  0xF000 to 0xF7FF", 13, 10, 13, 10, 0
mesg_ab:.db	"Abort, nothing erased", 13, 10, 0
mesg_do:.db	"Erasing... ", 0
mesg_ok:.db	"Ok", 13, 10, 0
mesg_er:.db	"Failed", 13, 10, 0
mesgany:.db	"Press any key", 0




