memtest prg?

Basic and Machine Language

Moderator: Moderators

User avatar
srowe
Vic 20 Scientist
Posts: 1325
Joined: Mon Jun 16, 2014 3:19 pm

memtest prg?

Post by srowe »

Before I go and write one is anyone aware of a good software-based memory tester? Something that is reasonably comprehensive (walking bits etc).

Thanks.
FD22
Vic 20 Hobbyist
Posts: 148
Joined: Mon Feb 15, 2010 12:31 pm

Re: memtest prg?

Post by FD22 »

Zimmers is usually good as a place to start looking for pre-written stuff.

I can post the routine I wrote for a project a couple of years back if you want something to build into your own code though (quote from the project blog back in January 2013):
Commodore ROM - RAMTAS entry point $FD8D: tests RAM from $0400 to $7FFF, initialises pages 0, 2, and 3 to zero, tracks the end of contiguous memory (i.e. the first empty block after $2000), ignores BLK5 ($A000) if it's RAM. Total cycles if RAM fully populated: 2,386,249

VIC++ ROM - RAMTAS entry point $C005: tests all memory from $0000 to $BFFF, initialises all memory to zero, tracks populated memory zones (doesn't care if there are 'holes'), includes BLK5 if populated with RAM, tests Colour RAM. Total cycles if RAM fully populated: 1,868,208
User avatar
srowe
Vic 20 Scientist
Posts: 1325
Joined: Mon Jun 16, 2014 3:19 pm

Re: memtest prg?

Post by srowe »

That would be great, thanks. I think my internal memory expansion has an intermittent fault so I want something akin to memtest86+ to keep scanning over a range of memory. It should be too hard to knock something up.
FD22
Vic 20 Hobbyist
Posts: 148
Joined: Mon Feb 15, 2010 12:31 pm

Re: memtest prg?

Post by FD22 »

Here you go.

Code: Select all


;; Zero Page
_TESTADDR	EQU $00				; memory test address (lo/hi)
_TESTDATA	EQU $02				; memory test address data
_TESTBITS	EQU $03				; memory test expansion RAM bitmap

;; VIC
_VIC		        EQU $9000			; VIC base address
_VCSCRNCO	EQU _VIC+15			; b7-4 = background colour; b3 = reverse mode; b2-0 = border colour

;; memory test page table
_MEMTAB         DC.B $01,$04,$10,$20,$40,$60,$80,$A0,$C0								; 9 bytes

cpureset	SUBROUTINE		reset handler - system initialisation [.A, .X, .Y, .SP]
			sei							; [2]	disable CPU interrupts
			cld							; [2]	clear decimal flag
			ldx #$01					; [2]	white screen/border
			stx _VCSCRNCO				; [4]	set VIC colour register
			dex							; [2]	ZP memory test location index (.X = #$00)
			ldy #$FF					; [2]
.nextzp		tya							; [2]	first ZP test bit-pattern (.Y = %11111111)
.zptest		sta $00,x					; [4]	ZP store pattern at ZP location with X offset
			cmp $00,x					; [4]	check it
			bne .testfail				; [2/3]	store failed, game over
			adc #$00					; [2]	add 1 in the carry flag to yield second test bit-pattern (%00000000)
			beq .zptest					; [3/2]	loop around to test next pattern
			inx							; [2]	increment location index
			bne .nextzp					; [3/2]	loop around to test next location
			iny							; [2]	main RAM address line / byte memory test address lo-byte index (.Y = $00)
			ldx #$07					; [2]	memory table index
.newblock	lda _MEMTAB,x				; [4]	get block test address start page
			sta _TESTADDR+1				; [3]	ZP store test address start page (hi-byte)
.nextbyte	lda #$FF					; [2]	first test bit-pattern (%11111111)
.bytetest	sta (_TESTADDR),y			; [6]	store pattern at indirect test address with .Y offset
			cmp (_TESTADDR),y			; [5]	check it
			beq .testpass				; [3/2]	store worked
			lda _MEMTAB+1,x				; [4]	get test address end page
			cmp #$04					; [2]	failure in 1K onboard?
			beq .testfail				; [2/3]	yep, critical failure
			cmp #$20					; [2]	failure in 4K onboard?
			beq .testfail				; [2/3]	yep, critical failure
			clc							; [2]	clear carry
			bcc .setbit					; [3/3]	set expansion bit
.testfail	jmp critfail				; [6]	no 3K at BLK0, game over
.testpass	adc #$00					; [2]	add 1 in the carry flag to yield second test bit-pattern (%00000000)
			beq .bytetest				; [3/2]	loop around to test next pattern
			iny							; [2]	next test address on current page
			bne .nextbyte				; [3/2]	loop back to first pattern
			lda _MEMTAB+1,x				; [4]	get test address end page
			inc _TESTADDR+1				; [5]	ZP increment memory test address page (hi-byte)
			cmp _TESTADDR+1				; [5]	ZP check for end of block
			bne .nextbyte				; [3/3]	continue test at next page
			cmp #$04					; [2]	1K onboard?
			beq .skipbit				; [2/3]	yep, no expansion bit
			cmp #$20					; [2]	4K onboard?
			beq .skipbit				; [2/3]	yep, no expansion bit
			sec							; [2]	set carry
.setbit		rol _TESTBITS				; [5]	ZP rotate carry into expansion RAM bitmap
			cmp #$C0					; [2]	did we just test 8K BLK5?
			bne .skipbit				; [3/2]	no, carry on
			dex							; [2]	double-decrement for the $A000 special case
.skipbit	dex							; [2]	decrement memory table index for next block
			bpl .newblock				; [3/2]	loop back if not finished
			ldx #$94					; [2]	colour memory start
			stx _TESTADDR+1				; [3]	ZP store test address start page (hi-byte)
			ldx #$98					; [2]	colour memory end
.nextnybl	lda #$0F					; [2]	first colour nybble test bit-pattern (%00001111)
.nybltest	sta _TESTDATA				; [3]	ZP store pattern at test data location
			sta (_TESTADDR),y			; [6]	store pattern at indirect test address with .Y offset
			lda (_TESTADDR),y			; [5]	get pattern
			and #$0F					; [2]	mask-off upper nybble
			cmp _TESTDATA				; [3]	ZP compare with test data
			bne .testfail				; [3/2]	store failed
			lda #$00					; [2]	second test bit-pattern (%00000000)
			cmp _TESTDATA				; [3]	ZP compare with test data
			bne .nybltest				; [3/2]	loop back for second test
			iny							; [2]	next test address on current page
			bne .nextnybl				; [3/2]	loop back to first pattern
			inc _TESTADDR+1				; [5]	ZP increment memory test address page (hi-byte)
			cpx _TESTADDR+1				; [5]	ZP check for end of block
			bne .nextnybl				; [3/2]	continue test at next page
			ldx #$04					; [2]	identifier byte index
.nextid		lda _EXPCART,x				; [4]	get next BLK5 autostart cart identifier byte
			cmp _STRTMSG1,x				; [4]	compare with byte in startup identifier message
			bne .initptrs				; [3/2]	identifier doesn't match - not a VIC++ cart
			dex							; [2]	decrement index
			bpl .nextid					; [3/2]	loop for next id byte
			jmp (_CARTCOLD)				; [5]	execute cartridge cold-start
.initptrs	ldx #$04					; [2]	expansion page table index
			ldy #$10					; [2]	top of symbol table page
			lda _TESTBITS				; [3]	ZP get temporary expansion RAM bitmap
			lsr							; [2]	shift 3K BLK0 bit to Carry
			bcs .savebits				; [3/2]	check for 3K at BLK0
			jmp critfail				; [6]	no 3K at BLK0, game over
.savebits	sta _RAMBITS				; [4]	save bitmap at permanent address
.nextbit	lsr							; [2]	shift 8K BLK1/2/3 bits to Carry
			bcc .skipclr				; [2/3]	skip the block when we get a clear bit
			ldy _MEMTAB,x				; [4]	get top of user-memory page for this 8K block
.skipclr	inx							; [2]	increment index pointer
			cpx #$06					; [2]	all 'standard' 8K bits done?
			bne .nextbit				; [3/2]	no, loop for next bit
			lsr							; [2]	shift 8K BLK5 bit to Carry
			bcc .noexp					; [2/3]	no change if we get a clear bit
			ldy #$C0					; [2]	top of symbol table page ($A000)
.noexp		sty _SYMTAB					; [4]	set top of symbol table page
			dey							; [2]	top of user-memory page (one page down from top of symbol table)
			sty _USERTOP				; [4]	set top of user-memory page
Apologies for the naff formatting - the version of the VIC++ source on this laptop predates my use of Notepad++, so tabs, spaces and line-breaks are all over the place, and I've since switched to an upper-case mnemonic standard because this was too hard to read. :?
User avatar
srowe
Vic 20 Scientist
Posts: 1325
Joined: Mon Jun 16, 2014 3:19 pm

Re: memtest prg?

Post by srowe »

Here's a useful article about memory testing in general

http://www.barrgroup.com/Embedded-Syste ... st-Suite-C

I'll see if I can knock something up in assembler.
User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: memtest prg?

Post by Mike »

srowe wrote:That would be great, thanks. I think my internal memory expansion has an intermittent fault so I want something akin to memtest86+ to keep scanning over a range of memory.
How does this fault show? As I see, your internal expansion fills the gap of the range $0400 to $0FFF and is wired so the original internal RAM still uses the original circuitry (except that special handling of the /RAMx signals).

As that internal expansion, like mine, was also designed to let VIC access it, I once wrote a detect algorithm for this. It first performs a simple memory test for the presence of RAM in that range, and then sets up a special display with a variant of bit walking data. While VIC displays this, the data being read can be fetched off by the CPU on the following cycle by reading off unconnected space (here, address $9200).

At the moment that is all my program does, check for the presence of that internal RAM expansion. I've included the source, and it could be extended to check for the correct wiring of the address lines. Here's the link: (download), detect.prg requires also an installed +8K RAM expansion.

The main problem remaining will be that a more thorough implementation will require to be put on ROM. However, the cartridge autostart sequence already performs a JSR instruction before jumping into cartridge code and thus relies on functioning RAM in $0100 .. $01FF. :?
User avatar
srowe
Vic 20 Scientist
Posts: 1325
Joined: Mon Jun 16, 2014 3:19 pm

Re: memtest prg?

Post by srowe »

How does this fault show? As I see, your internal expansion fills the gap of the range $0400 to $0FFF and is wired so the original internal RAM still uses the original circuitry (except that special handling of the /RAMx signals).
I'm seeing two (probably related) issues.

1. Random, changing corruption of a couple of bits of all characters
2. Corruption of BASIC programs (tokens changing to other tokens, lines getting garbage appended)

I think the first indicates that the data lines are faulty, the second is less clear.

I know that the height of the board means it contacts the keyboard above at one end of the ROM. I can 'fix' the character corruption by pressing firmly on the keyboard.

The wirewrap socket I used for the ROM is too tall really, I'm going to swap it for a pair of turned pin SIPs that I've got coming. I've a hunch that will fix both issues.
User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: memtest prg?

Post by Mike »

srowe wrote:I think the first indicates that the data lines are faulty, the second is less clear.
What output do you get from my test program then? Besides, adding the extra +8K locks off the internal expansion from BASIC use, so the fault can't disturb the running program.

If the access by VIC works, you'll see a short sequence on screen, where thin white vertical lines on black background expand until the screen is full white, and then they become thin again, followed by a printout of "INTERNAL 3K PRESENT!"

How did you handle the inputs of the original /RAMx signals to the 13-input NAND gate (UA1 on your 2-prong VIC-20)? Did you left them open, or did you tie them to H-level? When left open, this 'works', albeit barely (no safety margin on the H-levels at the open inputs) and UA1/UC6 might block access to your expansion because of stray capacitive coupling.
User avatar
srowe
Vic 20 Scientist
Posts: 1325
Joined: Mon Jun 16, 2014 3:19 pm

Re: memtest prg?

Post by srowe »

What output do you get from my test program then? Besides, adding the extra +8K locks off the internal expansion from BASIC use, so the fault can't disturb the running program.
I haven't had a chance to try it. We've had a medical emergency with a pet we're looking after.
How did you handle the inputs of the original /RAMx signals to the 13-input NAND gate (UA1 on your 2-prong VIC-20)?
I tied them to Vcc.
User avatar
srowe
Vic 20 Scientist
Posts: 1325
Joined: Mon Jun 16, 2014 3:19 pm

Re: memtest prg?

Post by srowe »

What output do you get from my test program then? Besides, adding the extra +8K locks off the internal expansion from BASIC use, so the fault can't disturb the running program.
I get a shifting black and white pattern followed by "INTERNAL 3K PRESENT!". Sometimes I don't get the message (but the pattern is the same).

Just ran it in a loop, it ran 23 times before failing.
User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: memtest prg?

Post by Mike »

srowe wrote:Sometimes I don't get the message (but the pattern is the same).
In that case, the detection bailed out with most of the patterns working but failing on the last one(s). With (just) an external +3K expansion, the test would already stop with the first pattern.

For the moment, this hints at problems with the upper bits (i.e. data bus connection dodgy).

You have, however also pointed me to a blatant omission of mine regarding my detection routine - I never tried to run it in a loop. As the method really relies upon the parasitic capacity of the data bus, that loop test should be done to confirm the reliability of this check. I'll do it these days on my VIC-20. :oops:

For the moment, you could try another program, HHM Display. Like the memory test, it again requires an extra +8K RAM expansion. This time, most of the internal RAM is used to display several bitmapped screens in a slide show, with overscan, on PAL, with 208x256 pixels. If there is really a dodgy connection of the data bus, I'd expect flickering pixels or character blocks (when VIC access is problematic) or pixels stuck at 0/1 (steady, when CPU access has issues). New pictures are loaded after a key press, while the display continues - please don't use any fast loaders as their timing is disturbed by the display routine in the NMI.
We've had a medical emergency with a pet we're looking after.
Did all go well with your pet?
User avatar
srowe
Vic 20 Scientist
Posts: 1325
Joined: Mon Jun 16, 2014 3:19 pm

Re: memtest prg?

Post by srowe »

HHM Display gives odd results. I can see there's some sort of picture but it's broken up in sections and there are parts that flicker randomly.

I've got my SIP now so I'll desolder the socket and replace it. I'll also check the circuit for bad joints and produce a schematic (I think I've lost the original).
Did all go well with your pet?
No, unfortunately it died.
User avatar
srowe
Vic 20 Scientist
Posts: 1325
Joined: Mon Jun 16, 2014 3:19 pm

Re: memtest prg?

Post by srowe »

Removing the board and replacing the character ROM results in scrambled characters. It looks like the wear and tear on the socket has made it unreliable. That's at least part of my problems.
User avatar
srowe
Vic 20 Scientist
Posts: 1325
Joined: Mon Jun 16, 2014 3:19 pm

Re: memtest prg?

Post by srowe »

So here's my memory test program. It runs a sequence of tests
  • data walking 1's
  • address walking 1's
  • write/read of every byte
It's currently located at $B000 (so I can burn it to EPROM when my 2732s arrive) but can be rebuilt at any location.

I've not gone overboard trying to make it fast or small. Suggestions for improvements welcome.
Attachments
memtest2.zip
Memtest prg and source
(3.6 KiB) Downloaded 109 times
User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: memtest prg?

Post by Mike »

srowe wrote:Removing the board and replacing the character ROM results in scrambled characters. It looks like the wear and tear on the socket has made it unreliable. That's at least part of my problems.
Even though my follow-up probably fits better into the Hardware section: in the meantime, did you have success sorting out those issues with the internal RAM expansion in your VIC-20?
Post Reply