/*--------------------------------------------------------------------------*\

    FILE....: WALK.CPP
    TYPE....: C++ Program
    AUTHOR..: David Rowe
    DATE....: 12/2/02

    Walking bit memory test program.

\*--------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*\

         Voicetronix Voice Processing Board (VPB) Software

         Copyright (C) 1999-2001 Voicetronix www.voicetronix.com.au

         This library is free software; you can redistribute it and/or
         modify it under the terms of the GNU Lesser General Public
         License as published by the Free Software Foundation; either
         version 2.1 of the License, or (at your option) any later version.

         This library 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.  See the GNU
         Lesser General Public License for more details.

         You should have received a copy of the GNU Lesser General Public
         License along with this library; if not, write to the Free Software
         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
	 USA

\*---------------------------------------------------------------------------*/

#include "vpbreg.h"
#include "generic.h"
#include "hip.h"

#include <cstdio>
#include <cstdlib>

#define SIZE_WD   0xffff
#define MAX_FAILS 10

int main(int argc, char *argv[]) {
	int               i,j;
	unsigned short    wr;
	unsigned short    rd;
	int               base;		    // ISA base addr or PCI board num
	int               fails = 0;
	int               length = SIZE_WD;

	if (argc < 2) {
		printf("usage: walk BASE\n");
		printf("e.g. for ISA 'walk 0x300' or 'walk 0x310'\n");
		printf("e.g. for PCI 'walk 0' or 'walk 1'\n");
		exit(0);
	}

	// init
	sscanf(argv[1], "%x", &base);
	if (argc == 3)
		sscanf(argv[2], "%x", &length);

	if(length <= 0 || length > SIZE_WD) {
		printf("Error: invalid length: %d\n", length);
		return -1;
	}

	// work out which device driver we are using for card 0.
	VPBRegister v;
	VPBREG      &vr = v.GetReg(0);

	// OK, init host interface port (HIP)
	Hip h = Hip(vr.ddmodel);

	// Place DSP in reset
	h.InitVpb(base);
	h.DspReset(0);

	for(i=0; i<length; i++) {
		for(j=0; j<16; j++) {
			wr = 1<<j;
			h.WriteDspSram(0, i, 1, &wr);
			h.ReadDspSram(0, i, 1, &rd);
			if (wr != rd) {
				printf("Error [0x%04x] wr = 0x%04x "
				       "rd = 0x%04x\n", i, wr, rd);
				fails++;
				if (fails == MAX_FAILS) {
					printf("FAILED!\n");
					exit(1);
				}
			}
		}
		printf("OK [0x%04x]\r", i);
	}

	if (fails)
		printf("\nFAILED!\n");
	else
		printf("\nPASSED!\n");

	return 0;
}

