2102 SRAM Tester
The 2102 is 1K Static ram chip packaged in a 16 pin dip package. It was introduced by Intel in 1972. This part was used by several early micro-computers including the Altair and SCELBI 8B. Here is my SUPERPROTO connected to a breadboard set up to test 2102 SRAMs. Note that the index card mounted on the SUPERPROTO itself is labelled wrong - it says 2101 tester, but should say 2102 tester. During several sessions of testing I tested 100 NOS 2102s and only found 1 bad one.
This test program was derived from the 1101 SRAM Tester. Please review that page before proceeding.
The Pin out is as follows and should be connected to the associated 6522A pins
| pin | function | 6522A connection |
| 1 | A6 | Port A - bit 6 |
| 2 | A5 | Port A - bit 5 |
| 3 | R/W | Port B - bit 4 |
| 4 | A1 | Port A - bit 1 |
| 5 | A2 | Port A - bit 2 |
| 6 | A3 | Port A - bit 3 |
| 7 | A4 | Port A - bit 4 |
| 8 | A0 | Port A - bit 0 |
| 9 | GND | |
| 10 | 5V | |
| 11 | Data In | Port B - bit 6 |
| 12 | Data Out | Port B - bit 7 |
| 13 | /Chip Enable | Port B - bit 5 |
| 14 | A9 | Port B - bit 1 |
| 15 | A8 | Port B - bit 0 |
| 16 | A7 | Port A - bit 7 |
Load the code into your SUPERPROTO, using the same technique as is used for the Diagnostic Program.
Use this aif file
load from cassette/ipod - 0800.A9EBR
copy to SUPERPROTO card loaded in slot 7
1A:00 08 EB A9 00 C7
900G
Run by typing slot# control-p from the monitor or PR#slot number from basic.
Each pass of the test takes a couple of minutes. Note that the 6502 isn't fast enough to check minimum timing values.
I use the 6502 cross assembler called "DASM". Source Code Follows:
PROCESSOR 6502
LIST ON
;-------------------------------------------------------------------------
; Defines - this code can be built one of four ways
; 1. to run in RAM
; 2. to run out of Hobbycard EEPROM
;
; select one of these three options
;-------------------------------------------------------------------------
;-------------------------------------------------------------------------
; Constants
;-------------------------------------------------------------------------
BS EQU $DF ;Backspace key, arrow left key
CR EQU $8D ;Carriage Return
ESC EQU $9B ;ESC key
PROMPT EQU "\" ;Prompt character
;-------------------------------------------------------------------------
; MONITOR FUNCTIONS
;-------------------------------------------------------------------------
COUT EQU $FDED ;Backspace key, arrow left key
IOSAVE EQU $FF4A ;Save all registers
IOREST EQU $FF3F ;Restore all registers
HOME EQU $FC58 ;Clear Screen
MOVE EQU $FE2C ;Move memory
MON EQU $FF65 ;Monitor entry point
SETKBD EQU $FE89 ;IN#0 sets default input vector
SETVID EQU $FE93 ;PR#0 sets default output vector
WAIT EQU $FCA8 ;wait function
PRBYTE EQU $FDDA ;print hex byte
NXTA4 EQU $FCB4 ;inc A4 and A1 until A1 = A2
;-------------------------------------------------------------------------
; I/O FUNCTIONS
;-------------------------------------------------------------------------
KEYBOARD EQU $C000 ;keyboard data
KEYSTROBE EQU $C010 ;clears keyboard data
;-------------------------------------------------------------------------
; 6522A FUNCTIONS
;-------------------------------------------------------------------------
TMR2L EQU $c088 ;timer2 low byte
; write: load LS byte
;
; read: to read low counter and clear interrupt
TMR2H EQU $c089 ;timer2 high byte
; wrt: high byte, transfer high and low to counter & enable int
; rd: read high counter
;
ACR EQU $c08B ;aux control register
;bit 5 = 0 timer 2 one shot mode
;bit5 = 1 timer 2 count pulses output on PB 6
;
IFR EQU $c08C ;interrupt flag register
; read: bit 7 state of IRQ, bit 5 timer 2 interrupt pending
; write: set bit to clear interrupt
;
IER EQU $c08E ;interrupt enable register
;bit 7 = 1 to set
;bit 7 = 0 to clear
;bit 5 = timer 2
;-------------------------------------------------------------------------
; Memory declaration
;-------------------------------------------------------------------------
WINDOWTOP EQU $22 ;top edge of window
HEX1L EQU $24 ;End address of dump block
HEX1H EQU $25
HEX2L EQU $26 ;Begin address of dump block
HEX2H EQU $27
SAVEINDEX EQU $28 ;Save index in input buffer
LASTSTATE EQU $29 ;Last input state
;unused by monitor or applesoft
; address setup for move command
AD1L EQU $1a
AD1H EQU $1b
AD2L EQU $1c
AD2H EQU $1d
AD4L EQU $1e
AD4H EQU $1f
;address holding locations for monitor move command
A1L EQU $3c
A1H EQU $3d
A2L EQU $3e
A2H EQU $3f
A4L EQU $42
A4H EQU $43
IN EQU $0200 ;Input buffer
WORKING EQU $0800 ;Working Memory
FLIP EQU $C020 ;Output flip-flop
TAPEIN EQU $C060 ;Tape input
KBD EQU $C000 ;keyboard input
KBDCR EQU $C010 ;keybaord strobe clear
;---------------------------------------------------------------------------
; build in ACI Driver
;---------------------------------------------------------------------------
;BLD4RAM EQU 0
IFCONST BLD4RAM
ORG $800 ; build for memory
ELSE
ORG $c700 ; plug in hobbyboard
ENDIF
START:
BIT $20 ; pretend this is Disk 2, so autostart will run it automatically
BIT $00
BIT $03
BIT $3C
;------------------------------------------------------------------------
; make sure no other card has 2K block selected
;--------------------------------------------------------------------------
LDA $CFFF ;
;------------------------------------------------------------------------
; now figure out our slot
;--------------------------------------------------------------------------
JSR IOSAVE ; save registers
SEI ; block interrupts
JSR $FF58 ; move current PC to stack
TSX
IFCONST BLD4RAM
LDA #$01 ; build for memory
ELSE
LDA $0100,X ; fetch high address
ENDIF
STA $07F8 ; save currently active card
AND #$07 ; mask off $CX to get slot #
TAY
ASL
ASL
ASL
ASL
TAX ; can be used to access 6522 VIA at C0SX
STA $478,y ;save in scratchpad register
LDA #0 ;initialize pass count
STA $4f8,y ;save in scratchpad register
STA $6f8,y ;save interrupt count
;
; restore normal COUT and CIN
;
JSR SETKBD
JSR SETVID
JSR HOME ;clear screen
;
; print banner
;
LDA #>BANNER
STA A1H
LDA #<BANNER
STA A1L
JSR PRINTSTRING
LDA #1 ; prevents banner from being scrolled off top
STA WINDOWTOP
LDA #>TESTSTART
STA A1H
LDA #<TESTSTART
STA A1L
JSR PRINTSTRING
;
; initialize 6522A ports
; port A - output - 8 bit SRAM address bus
PORTA EQU $C081 ; PORT A
PORTADIR EQU $C083 ; PORT A direction
;
PORTB EQU $C080 ; PORT B
PORTBDIR EQU $C082 ; PORT B direction
;
; port B - output - bit's 0 and 1 = address bits 8 and 9
PORTB_A8A9 EQU $03
; port B - output - bit 4 = low read - high write
PORTB_RW EQU $10
; port B - output - bit 5 = chip select
PORTB_CS EQU $20
; port B - output - bit 6 = SRAM write data (in) bit
PORTB_WD EQU $40
; port B - input - bit 7 = SRAM data out
PORTB_RD EQU $80
LDA $07F8 ; fetch currently active card
AND #$07 ; mask off $CX to get slot #
ASL
ASL
ASL
ASL
TAX ; can be used to access 6522 VIA at C0SX
;set up address
LDA #$0
STA PORTA,X ; start with address "0"
LDA #$FF
STA PORTADIR,X ; set port A for output (address)
; set up control
LDA #PORTB_CS | PORTB_RW ; dessert Chip select and put in read mode
STA PORTB,X ; write data 0
;
LDA #PORTB_CS | PORTB_RW | PORTB_WD | PORTB_A8A9
STA PORTBDIR,X ; set port B direction
STRTTEST:
JSR SRAMTEST
BCS BADBIT ; error
LDA KEYBOARD ; check to see if keyboard input (stops test)
BMI TESTEXIT ; yes clear strobe, print finished and back to monitor
;
; finished pass, increment count and print banner
;
LDA #>PASSED
STA A1H
LDA #<PASSED
STA A1L
JSR PRINTSTRING
LDA $07F8 ; save currently active card
AND #$07 ; mask off $CX to get slot #
TAY
LDA $4F8,Y ;fetch pass count
TAX
INX ;increment count
TXA
STA $4f8,Y ;save count
JSR PRBYTE ;print hex number
LDA #$8d
JSR COUT ;newline
SEC
BCS STRTTEST
BADBIT:
PHA
LDA #>ERRORRED
STA A1H
LDA #<ERRORRED
STA A1L
JSR PRINTSTRING
PLA
JSR PRBYTE ;print hex number
SEC
BCS RETURNMON
TESTEXIT:
LDA KEYSTROBE ;clear keyboard strobe
LDA #>ABORTED
STA A1H
LDA #<ABORTED
STA A1L
JSR PRINTSTRING
;
; return to monitor
;
RETURNMON:
LDA #0 ; reset window top
STA WINDOWTOP
JMP MON
IFCONST BLD4RAM
ORG $0900 ; build for memory
ELSE
ORG $C800 ; plug in hobbyboard:w
ENDIF
;
; MOVE from A1 to A4 - until A1 = ending address in A2
;
MOV:
LDY #0 ; index = 0
LDA AD1L
STA A1L
LDA AD1H
STA A1H
LDA AD2L
STA A2L
LDA AD2H
STA A2H
LDA AD4L
STA A4L
LDA AD4H
STA A4H
MOV2:
LDA (A1L),Y ; MOVE A1[0x3C] TO A2[0x3E] TO
STA (A4L),Y ; A4[0x42]
MOVEWAIT:
CMP (A4L),Y ; for eeprom - wait till write takes
BNE MOVEWAIT ; MSB not correct until write is done
JSR NXTA4
BCC MOV2
RTS
GOTOBRKTEST:
JMP BRKTEST
SRAMTEST:
LDA $07F8 ; fetch currently active card
AND #$07 ; mask off $CX to get slot #
ASL
ASL
ASL
ASL
TAX ; can be used to access 6522 VIA at C0SX
;
; write zeros
;
LDY #0 ; low address bits
STY AD1H ; save high address bits
WRITENEXT0BIT:
CLC
JSR WRITEBIT
INY
BNE WRITENEXT0BIT
;
; 256 bits checked, wrap to next page
;
INC AD1H
LDA #$04 ; check for all 1K checked
BIT AD1H
BEQ WRITENEXT0BIT ; no, continue
;
; read all locations looking for zero
;
STY AD1H ; reset high address bits
READNEXT0BIT:
CLC
JSR READBIT
BCS GOTOBRKTEST
INY
BNE READNEXT0BIT
;
; 256 bits checked, wrap to next page
;
INC AD1H
LDA #$04 ; check for all 1K checked
BIT AD1H
BEQ READNEXT0BIT ; no, continue
;
; write all ones
;
STY AD1H ; reset high address bits
WRITENEXT1BIT:
SEC
JSR WRITEBIT
INY
BNE WRITENEXT1BIT
;
; 256 bits checked, wrap to next page
;
INC AD1H
LDA #$04 ; check for all 1K checked
BIT AD1H
BEQ WRITENEXT1BIT ; no, continue
;
; read all locations looking for ones
;
STY AD1H ; reset high address bits
READNEXT1BIT:
SEC
JSR READBIT
BCS GOTOBRKTEST
INY
BNE READNEXT1BIT
;
; 256 bits checked, wrap to next page
;
INC AD1H
LDA #$04 ; check for all 1K checked
BIT AD1H
BEQ READNEXT1BIT ; no, continue
;
; write and verify floating ones
;
;
; first write all zeros
;
STY AD1H ; reset high address bits
WRITENEXT0S:
CLC
JSR WRITEBIT
INY
BNE WRITENEXT0S
;
; 256 bits checked, wrap to next page
;
INC AD1H
LDA #$04 ; check for all 1K checked
BIT AD1H
BEQ WRITENEXT0S ; no, continue
STY AD2L ; start with bit zero
STY AD2H ; start with page zero
;
; now loop - writing single bit into each location and checking that only that one bit is set
;
READNEXTFLOAT1BITINCBIT:
LDY AD2L ; address of floating bit
LDA AD2H ; page #
STA AD1H ; set up high two bits of address (page)
SEC
JSR WRITEBIT ; set single bit at location Y
;
; read all locations looking for zero - except location of interest
;
LDY #0
STY AD1H ; starting page 0
READNEXTFLOAT1BIT:
; is this the bit that should be 1
CPY AD2L ;current bit in page?
BNE READNEXTFLOAT1BITZERO ;nope, we should read zero
LDA AD2H
CMP AD1H ; correct page?
BNE READNEXTFLOAT1BITZERO ;nope, we should read zero
; found the bit
SEC ; expect to see the floating one
BCS READNEXTFLOAT1BITONE
READNEXTFLOAT1BITZERO:
CLC
READNEXTFLOAT1BITONE:
JSR READBIT
BCS BRKTEST
INY
BNE READNEXTFLOAT1BIT
;
; 256 bits checked, wrap to next page
;
INC AD1H
LDA #$04 ; check for all 1K checked
BIT AD1H
BEQ READNEXTFLOAT1BIT ; no, continue
;
; done checking bit, now advance to next bit
;
LDA AD2H
STA AD1H ; set page
LDY AD2L
CLC
JSR WRITEBIT ; clear previous single bit at location Y
INC AD2L
BNE READNEXTFLOAT1BITINCBIT
INC AD2H
LDA #$04 ; check for all 1K checked
BIT AD2H
BEQ READNEXTFLOAT1BITINCBIT ; no, continue
;
; write and verify floating zeros
;
;
; first write all ones
;
LDY #0
STY AD1H ; reset high address bits
WRITENEXT1S:
SEC
JSR WRITEBIT
INY
BNE WRITENEXT1S
;
; 256 bits written, wrap to next page
;
INC AD1H
LDA #$04 ; check for all 1K checked
BIT AD1H
BEQ WRITENEXT1S ; no, continue
STY AD2L ; start with bit zero
STY AD2H ; start with page zero
;
; now loop - writing single bit into each location and checking that only that one bit is clear
;
READNEXTFLOAT0BITINCBIT:
LDY AD2L ; address of floating bit
LDA AD2H ; page #
STA AD1H ; set up high two bits of address (page)
CLC
JSR WRITEBIT ; clear single bit at location Y
;
; read all locations looking for zero - except location of interest
;
LDY #0
STY AD1H ; starting page 0
READNEXTFLOAT0BIT:
; is this the bit that should be 0
CPY AD2L ;current bit?
BNE READNEXTFLOAT0BITONE ;nope, we should read one
LDA AD2H
CMP AD1H ; correct page?
BNE READNEXTFLOAT0BITONE ;nope, we should read one
CLC ; expect to see the floating zero
BCC READNEXTFLOAT0BITZERO
READNEXTFLOAT0BITONE:
SEC
READNEXTFLOAT0BITZERO:
JSR READBIT
BCS BRKTEST
INY
BNE READNEXTFLOAT0BIT
;
; 256 bits checked, wrap to next page
;
INC AD1H
LDA #$04 ; check for all 1K checked
BIT AD1H
BEQ READNEXTFLOAT0BIT ; no, continue
;
; done checking bit, now advance to next bit
;
LDA AD2H
STA AD1H ; set page
LDY AD2L
SEC
JSR WRITEBIT ; set previous single bit at location Y
INC AD2L
BNE READNEXTFLOAT0BITINCBIT
INC AD2H
LDA #$04 ; check for all 1K checked
BIT AD2H
BEQ READNEXTFLOAT0BITINCBIT ; no, continue
CLC
BRKTEST:
TYA
RTS
;
; A = address, Carry set for 1, Carry not set for zero
;
WRITEBIT:
TYA
STA PORTA,X ; set address (low 8 bits)
LDA AD1H ; fetch high address bits
ORA #PORTB_CS ; write (yes), CS (not yet) - default data=0
BCC WRITEBIT0 ; input c is 0, then skip 0 set
ORA #PORTB_WD ; carry in means data = 1
WRITEBIT0:
STA PORTB,X ; set to write with appropriate data bit
AND #<~PORTB_CS
STA PORTB,X ; add CS - starts write
ORA #PORTB_CS
STA PORTB,X ; remove CS - ends write
ORA #PORTB_RW
STA PORTB,X ; remove write
RTS
;
; input: A = address, carry set if expect a 1, otherwise a 0
; output: carry set if error
;
READBIT:
TYA
STA PORTA,X ; set low 8 bits of address
LDA AD1H ; fetch high address bits
ORA #PORTB_CS | PORTB_RW ; or in READ - do not assert CS yet
STA PORTB,X ; set read and address
AND #<~PORTB_CS
STA PORTB,X ; assert CS - starts read
LDA PORTB,X ; read data (bit7)
BCC READBIT0 ; carry coming in is clear, expect 0 bit
BMI READBITNOERR ; 1 expected, N is set - no error
READBITERR:
IFCONST BLD4RAM
CLC ; test code running in RAM - always pass
BCC READBITDONE ; always branch
ELSE
SEC ; error indication
BCS READBITDONE ; always branch
ENDIF
READBIT0: ;
BMI READBITERR ; should be 0, was 1 - then error
READBITNOERR:
CLC ;equal - no error
READBITDONE:
LDA AD1H ; fetch high address bits
ORA #PORTB_CS | PORTB_RW ; dessert Chip select and leave in read mode
STA PORTB,X ;
RTS
PRINTSTRING:
LDY #0
PS1:
LDA (A1L),Y
BEQ PSDONE
ORA #$80
JSR COUT
INY
BNE PS1
PSDONE:
RTS
BANNER: DC "2102 TEST COPYRIGHT 2012 MIKE WILLEGAL",$0d,0
TESTSTART: DC "STARTING TEST",$0d,0
PASSED: DC "PASS: ",0
ABORTED: DC "TEST STOPPED BY KEYBOARD INPUT",$0d,0
ERRORRED: DC "ERROR: ",0
