28256 EEPROM Programmer
This project describes how to build a simple programmer for a 28256 EEPROM.
![]() |
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:
Commands available are:
|
Here is the programmer 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 ;***************************************************************