28256 EEPROM Programmer

This project describes how to build a simple programmer for a 28256 EEPROM.

EEPROM Programmer The programmer hardware consists of an 28-pin socket for the 28256, two 74HC573 Octal transparent Latches, and two 14 pin headers for connecting to the SBC2's onboard 65C22.   Please note that this can be adapted for use with any 65C22.   This programmer should also work for other types of EEPROM (with some modifications).

The source data should be loaded into RAM and the zero-page pointers initialized before starting this program.   Since the EEPROM is 32k and the SBC-2 only has about 30k of RAM available, its best to program the EEPROM in two 16k part.

I recommend loading your 16K data into RAM from $1000 to $4FFF.   The zero page pointers would be set up like this:
$10 - 00
$11 - 00 (for the lower 16k, 40 for the upper 16k)
$12 - 00
$13 - 10
$14 - 00
$15 - 50

Commands available are:
R - Read EEPROM and print the contents to the screen (RAM is not altered)
W - Write RAM to EEPROM
C - Compare RAM with the EEPROM, print the mismatches to the screen.
E - Erase the EEPROM (fill with $FF)
Q - Quit the program

Here is the programmer schematic:
Schematic

The software driver includes commands to read, write, compare, and erase the EEPROM memory.   Here is the source code for the driver:

;=======================================================================
;                                                                      |
;          SSSSSSS    BBBBBB     CCCCCC                222222          |
;         S      S   B      B   C      C              2      2         |
;        SS         B      B   C                           2           |
;         SSSS     BBBBBBB    C          ========       2              |
;            SS   B      B   C                       2                 |
;     S      S   B      B   C      C              2                    |
;     SSSSSSS   BBBBBBB     CCCCCCC               22222222             |
;                                                                      |
;=======================================================================
;
;//****************************************************************//
;// Routine to program a 28256 EEPROM a 65C22 VIA                  //
;// By Daryl Rictor  (c) June 22, 2003   http://65c02.tripod.com/  //
;//****************************************************************//
;
; This program was tested and ran from my SBC-2 board running at
; 2MHz.  Any 65c02-based computer with a 6522 VIA should be able
; to use this code.
;
; *** This is a hobby-grade programmer.  
;
; Source data should be loaded into RAM prior to running this program.
; The zero page pointers must also be set up prior to running this 
; program.
; ----------------------------------------------------------------------
; VIA connections
;
; Port A - 2-way data bus
; Port B - Control bus
;    B0 - Low Address Latch
;    B1 - High Address Latch
;    B2 - /Read
;    B3 - /Write
;    B4 - /CS
;
;
;*** I/O Locations *******************************
; define the i/o address of the Via1 chip
;*** 6522 CIA ************************************
CTRL		=     	$7f50		; Port B
DATA		=     	$7f51		; Port A
DDRB		=     	$7f52		; Port B DDR
DDRA		=     	$7f53		; Port A DDR
;
; CONSTANTS
;                                       B(4 3210)
DISABLE     	=     	$FC		; 1 1100 make all signals to EEPROM & latches inactive
READ        	=     	$08		; 0 1000 Lower /CS /OE
WRITE       	=     	$04		; 0 0100 Lower /CS /WR
ADDRL       	=     	$Fd		; 1 1101 raise pin B0
ADDRH       	=     	$Fe		; 1 1110 raise pin B1
OUT         	=     	$FF		; DDR output mask
IN          	=     	$00		; DDR input mask
;
; Zero page Variables
;
eal		=	$10		; EEPROM Address Counter Low
eah		=	$11		; EEPROM Address Counter High
sal		=	$12		; Starting RAM address low
sah		=	$13		; Starting RAM address high
lal		=	$14		; Ending RAM address low
lah		=	$15		; Ending RAM address high
d		=	$16		; temp data register
tal		=	$17		; Current (temp) RAM address low
tah		=	$18		; Current (temp) RAM address high
al		=	$19		; EEPROM Address Counter Low
ah		=	$1A		; EEPROM Address Counter High
mask		=	$1b		; mask for write mode 0=write, FF=fill

;*************************************************************
; Main Program
;*************************************************************
		*= 	$800		; start anywhere
Init		lda	#OUT		
		sta	DDRB		; set control port for output
		lda   	#DISABLE
		STA   	CTRL 		; disable access to the EEPROM
		LDA   	#IN
		sta	DDRA		; set data port as input
Cmd		jsr   	prtcrlf		; move cursor to new line
		ldx	#$00
cmd1		lda   	cprompt,x
		beq   	cmd2
            	jsr   	Chrout
            	inx
		jmp   	cmd1		; Print the command prompt
cmd2        	jsr   	Chrin		; get a command input
            	and   	#$DF		; mask out lower case keys
            	cmp   	#"R"            ; R = read
            	bne   	cmd3		; 
		jmp   	eeread		; read the eeprom and display its contents to the screen
cmd3		cmp   	#"W"		; W = Write
            	bne   	cmd4
		jmp   	eewrite		; write ram into eeprom
cmd4		cmp   	#"E"		; E=Erase
            	bne   	cmd5
		jmp   	eeerase		; erase the eeprom
cmd5		cmp   	#"C"		; C=Compare
            	bne   	cmd6
		jmp   	eecomp		; compare eeprom with ram, report mismatches
cmd6		cmp   	#"Q"		; Q=quit
           	bne   	cmd
		jmp   	eequit          ; quit 
cprompt     	.byte	"$10-$11=EE start $12-$13=RAM start $14-$15=RAM end"
		.byte   $0d, $0a
		.byte 	"Enter Command (R)ead, (W)rite, (C)ompare, (E)rase, (Q)uit :"
		
		
            	.byte  	$00
;*************************************************************
; READ EEPROM
;*************************************************************
eeread      	jsr   	prtcrlf		; new line
            	ldx   	#$00
eerd1       	lda   	rprompt,x
            	beq   	eerd2
            	jsr   	chrout
            	inx
            	jmp   	eerd1		; prompt to continue
eerd2       	jsr   	chrin		; wait for keypress
            	cmp   	#$1b    	; esc will abort	
            	bne   	eerd3
            	jmp   	init		; abort
eerd3		lda   	eal		;
		sta	al		;
		lda	eah
		sta	ah		; init EEPROM address counter to 0
eerdlp		LDA   	#OUT
		sta	DDRA		; set data port to output
		lda	al
            	sta   	DATA		; write low address byte to data port
		LDA   	#ADDRL
		sta   	CTRL		; strobe the address into the latch
            	ldy   	#$00
eerd4		dey
		bne	eerd4		; delay
		lda   	#DISABLE
		sta   	CTRL		; restore latch strobe
		lda   	ah
		sta	DATA		; write high address byte to data port
		lda   	#ADDRH
		sta   	CTRL		; strobe the address into the latch
		ldy 	#$00
eerd5		dey
		bne	eerd5		; delay
		lda	#DISABLE
		sta	CTRL		; restore latch strobe
		LDA   	#IN		
		sta	DDRA		; set data port to input
		LDA	#READ
		STA	CTRL		; set EEPROM to read mode /cs & /oe
		nop
            	lda	DATA		; read byte from dataport
		sta 	d		; save it in temp storage
		lda	#DISABLE
		STA	CTRL		; disable EEPROM
		lda	ah
		ldx	al
		jsr   	prt2B		; print the address HHLL
		lda	#":"		
		jsr   	chrout		; print :
		lda	d
		jsr   	prt1B		; print the data byte  (HHLL:DD)
		jsr   	prtcrlf		; new line 
            	inc   	al
		bne	eerd6		; inc EEPROM address counter
		inc	ah		;
		bpl   	eerd6		; 	
		jmp	init		; end of EEPROM - we are done
eerd6		jmp	eerdlp
rprompt     	.byte  	"Press any key when ready, (Esc) to abort..."
  		.byte	$00
;*************************************************************
; WRITE EEPROM
;*************************************************************
eewrite		lda	#$00		;
		sta	mask
eewrite1	jsr   	prtcrlf		; new line
            	ldx   	#$00
eewr1       	lda   	rprompt,x
            	beq   	eewr2
           	jsr   	chrout
           	inx
            	jmp   	eewr1		; prompt to continue
eewr2       	jsr   	chrin		; wait for a keypress
            	cmp   	#$1b    	; esc = abort
           	bne   	eewr3
            	jmp   	init		; abort
eewr3		lda   	eal		;
		sta	al		;
		lda	eah
		sta	ah		; init EEPROM address counter to 0
		lda	sal
		sta	tal		;
		lda	sah
		sta	tah		; load starting RAM address into RAM addresscounter
eewrlp		LDA   	#OUT
		sta	DDRA		; set data port to output
		lda	al
            	sta   	DATA		; output EEPROM address counter low byte to data port
		LDA   	#ADDRL
		sta   	CTRL		; strobe the low byte address latch
            	ldy   	#$00
eewr4		dey
		bne	eewr4		; delay
		lda   	#DISABLE
		sta   	CTRL		; restore the latch strobe
		lda   	ah
		sta	DATA		; output EEPROM address counter high byte to data port
		lda   	#ADDRH
		sta   	CTRL		; strobe the high address latch
		ldy 	#$00
eewr5		dey
		bne	eewr5		; delay
		lda	#DISABLE
		sta	CTRL		; restore the latch strobe
		LDA   	#OUT
		sta	DDRA		; data port set to output
		lda	(tal)		; read data from RAM address counter
		ora	mask		; will be 0 for write, FF for erase
		sta	DATA		; store it to the data port
		nop			; delay
		LDA	#WRITE			
		STA	CTRL		; strobe the EEPROM's write mode  /cs & /wr
		nop			; delay
		lda	#DISABLE
		STA	CTRL		; disable EEPROM write
		lda	#IN
		sta	DDRA		; data port set to input
		lda	#READ
		sta	CTRL		; read back the EEPROM
		ldx	#$00	
		ldy	#$80		; set test timer to $8000
eewr55		dex
		bne	eewr57
		dey	
		bne	eewr57
		jmp	wrerror		; test timer ran out - write error encountered
eewr57		lda	data		; read EEPROM data
		cmp	(tal)		; compare it to the RAM byte
		bne	eewr55		; if not equal, dec Test Timer
		lda	#DISABLE
		sta	CTRL		; match - write cycle completed successfully	
            	inc   	al
		bne	eewr6
		inc	ah		; inc the EEPROM address counter
		bpl   	eewr6		; 
		jmp	init		; the EEPROM address counter has reached the end - exit write routine
eewr6		inc	tal
		bne	eewr65
		inc	tah		; increment the RAM address counter
eewr65		lda	lah
		cmp	tah
		bne	eewr7
		lda	lal
		cmp	tal		; have we reached the last byte to WRITE?
		bne	eewr7		; no 
		jmp	init		; yes - exit
eewr7		jmp	eewrlp		; no, do next write
;*************************************************************
; COMPARE EEPROM to RAM
;*************************************************************
eecomp      	jsr   	prtcrlf		; new line
            	ldx   	#$00
eecp1       	lda   	rprompt,x
            	beq   	eecp2
            	jsr   	chrout
            	inx
            	jmp   	eecp1		; prompt to continue
eecp2       	jsr   	chrin		; wait for keypress
            	cmp  	#$1b    	; esc pressed
            	bne   	eecp3		; no, continue
            	jmp   	init		; yes, start over
eecp3		lda   	eal
		sta	al
		lda	eah
		sta	ah		; reset EEPROM Address to $0000
		lda	sal
		sta	tal		
		lda	sah
		sta	tah		; move start RAM address to RAM Address Counter
eecplp		LDA   	#OUT
		sta	DDRA		; data port to output
		lda	al
            	sta   	DATA		; EEPROM Address low byte to dataport
		LDA   	#ADDRL
		sta   	CTRL		; raise the low address latch strobe
            	ldy   	#$00
eecp4		dey
		bne	eecp4		; delay
		lda   	#DISABLE
		sta   	CTRL		; lower the low address latcvh strobe
		lda   	ah
		sta	DATA		; EEPROM Address low byte to dataport
		lda   	#ADDRH
		sta   	CTRL		; raise the high address latch strobe
		ldy 	#$00
eecp5		dey
		bne	eecp5		; delay
		lda	#DISABLE
		sta	CTRL		; lower the high address latch strobe
		LDA   	#IN
		sta	DDRA		; data port to input
		LDA	#READ
		STA	CTRL		; EEPROM read command
		nop
            	lda	DATA		; read in the EEPROM data
		sta 	d		; save it in temp storage
		lda	#DISABLE
		STA	CTRL		; disable the EEPROM
		lda   	(tal)		; get RAM data
		cmp	d		; compare with EEPROM data
		beq	eecp55		; Equal
            	jmp	cperror		; not equal - print mismatch message
eecp55		inc   	al
		bne	eecp57		
		inc	ah		; inc EEPROM address Counter
eecp57		inc	tal
		bne	eecp58
		inc	tah		; inc RAM address counter
eecp58		lda	lah
		cmp	tah
		bne	eecp6
		lda	lal
		cmp	tal		; have we reached the last byte in RAM to compare?
		bne	eecp6
		jmp	init		; yes, start over
eecp6		jmp	eecplp		; no, get next byte
;*************************************************************
; FILL EEPROM with $FF's
;*************************************************************
eeerase		lda	#$FF
		sta	mask		; set erase mode
		jmp	eewrite1	; reuse write code	

;*************************************************************
; Exit to OS
;*************************************************************
eequit		RTS			; exit to OS

;*************************************************************
; Write Error messages
;*************************************************************
cperror		jsr   	prtcrlf		; new line
		ldx	#$00
cperr1		lda	cperrdat,x	; write compare error
		beq	wrerr2		; message done, 
		jsr	chrout
		inx
		jmp	cperr1		
cperrdat	.byte	"Compare ERROR at->"
; 
wrerror		jsr	prtcrlf		; new line
		ldx	#$00
wrerr1		lda	wrerrdat,x	; write "write error"
		beq	wrerr2		; message done
		jsr	chrout
		inx
		jmp	wrerr1
wrerr2		lda	ah		 
		ldx	al
		jsr   	prt2B		; print EEPROM address HHLL
		lda	#":"		
		jsr   	chrout		; print :
		lda	d
		jsr   	prt1B		; print data DD
		jsr	prtcrlf		; new line
		jmp	init		; start over
wrerrdat	.byte  	"Write ERROR at->"
		.byte  	$00
;*************************************************************
; Printing Subroutines
;*************************************************************
prtcrlf     	lda   	#$0d		; print CR
		jsr   	Chrout
		lda   	#$0a		; print LF
		jsr   	Chrout
            	rts			; return
Prt2B     	JSR   	Prt1B		; prints AAXX hex digits
            	TXA                     ;
Prt1B     	PHA                     ;  prints AA hex digits
            	LSR                     ;  MOVE UPPER NIBBLE TO LOWER
            	LSR                     ;
            	LSR                     ;
            	LSR   	                ;
            	JSR   	PrtDig          ;
            	PLA			;
PrtDig      	PHY                     ;  prints A hex nibble (low 4 bits)
            	AND   	#$0F            ;
            	TAY                     ;
            	LDA   	Hexdigdata,Y    ;
            	PLY                     ;
            	jmp   	chrout          ;
hexdigdata  	.byte  	"0123456789ABCDEFX"
;
; SBC-2 input and output vectors
;
Chrin		jmp 	($03eb)     
Chrout      	jmp 	($03F1)
;
;*************************************************************
; end
;***************************************************************


Home
All info provided "as-is" and is Copyright 2003.