/***************************************************************** ** D O W N L O A D . C ** Address Tracing System, Scott Harrington, Fall 94 ** Downloads a Xilinx RBT file (rawbits format) to the FPGA(s) on ** the Bullwinkle board. ** ** Command line options: ** [-p port] port #(200,220,240,...,3E0) default 300 ** [-s segment] segment D or E (default D) ** filename */ #include <stdio.h> #include <conio.h> #include <stdlib.h> #include <string.h> #include <dos.h> #define STAT_Empty0 0x01 #define STAT_Empty1 0x02 #define STAT_Empty2 0x04 #define STAT_Empty3 0x08 #define STAT_nExtract 0x10 #define STAT_nProgram 0x20 #define STAT_nInit 0x40 #define STAT_SACK 0x80 #ifndef INTERACTIVE #define kbhit() (1) #define getch() (32) #endif enum {OUT_Config=0, OUT_NOP1, OUT_StartWrite, OUT_StartRead, OUT_Remote, OUT_Local, OUT_E000, OUT_D000, OUT_Sel0, OUT_Sel1, OUT_Sel2, OUT_Sel3, OUT_UnSelAll, OUT_SelAll, OUT_NOP14, OUT_Reset}; #define IMAGESIZE 60000 unsigned char far image[IMAGESIZE]; unsigned int ioPort = 0x300; int page_E = 0; long download(FILE *rbt); void writeMem8(unsigned char val); unsigned int readMem16(void); int showStatLoop(void); int fillBoris(long count, unsigned int val); int emptyBoris(void); void main(int argc, char *argv[]) { int i, ch; long c, cw; char *parmstr, *endptr; FILE *rbtfile; char filename[255]; for (i=1; i<argc; i++) { if (argv[i][0] == '-') { switch (argv[i][1]) { case 'p': parmstr = (argv[i][2]) ? &argv[i][2] : argv[++i]; ioPort = (unsigned int)strtoul(parmstr, &endptr, 0); break; case 's': parmstr = (argv[i][2]) ? &argv[i][2] : argv[++i]; page_E = (parmstr[0] == 'E' || parmstr[0] == 'e'); break; default: printf("Usage: %s [-p port] [-s D000|E000] filename[.rbt]\n", argv[0]); exit(-1); } } else { strcpy(filename, argv[i]); if ((rbtfile=fopen(filename, "rb")) != NULL) break; strcat(filename, ".rbt"); if ((rbtfile=fopen(filename, "rb")) != NULL) break; printf("Unable to open file %s.\n", filename); exit(-1); } } if (ioPort & ~0x3E0) { printf("Valid ports are 0x200, 220, 240, ..., 3E0.\n"); exit(-1); } if (rbtfile == NULL) { printf("Usage: %s [-p port] [-s D000|E000] filename[.rbt]\n", argv[0]); exit(-1); } showStatLoop(); /* Prepare Bullwinkle for configuration */ printf("Preparing for FPGA configuration using port %x, mem loc %s.\n", ioPort, page_E ? "E000:0000" : "D000:0000"); outportb(ioPort+OUT_Config, 0); outportb(ioPort+OUT_Local, 0); outportb(ioPort+(page_E ? OUT_E000:OUT_D000), 0); outportb(ioPort+OUT_SelAll, 0); printf("Waiting for Init signals to deactivate"); while ((inportb(ioPort) & STAT_nInit) == 0) { if (kbhit()) { if (getch() == 27) exit(0); } putchar('.'); } printf("\n"); showStatLoop(); printf("Downloading %s to FPGA.\n", filename); c = download(rbtfile); printf("Total bits written to FPGA = %ld\n", c); showStatLoop(); } long download(FILE *rbt) { long cnt = 0L; long len; long index = 0; int i; char ch; len = fread(image, 1, IMAGESIZE, rbt); /* look for 11111111 start bit pattern in rbt file */ while (cnt<8L) { ch = image[index++]; cnt = (ch=='1') ? cnt+1L : 0L; } /* send start bits */ cnt = 0L; while (cnt < 8L) { writeMem8(0x01); cnt += 1L; } /* send bits in rbt until eof */ for ( ; index<len; index++) { ch = image[index]; // if (ch == '0' || ch == '1') { if (ch & 0x30) { writeMem8(ch); cnt += 1L; if (cnt%1000L == 0L) putchar('.'); } } /* send an additional few ones to keep CCLK going for a while */ for (i=0; i<40; i++) writeMem8(0x01); printf("\n"); return cnt; } int showStatLoop() { unsigned int d, d0=256; int c; #ifdef INTERACTIVE printf("\nPress any key to continue (ESC aborts).\n"); #endif while (1) { d = inportb(ioPort); if (d != d0) { printf("%s %s %s %s Empty:%d%d%d%d\n", (d & STAT_SACK) ? "SACK":"sack", (d & STAT_nInit) ? "init":"INIT", (d & STAT_nProgram) ? "pgm":"PGM", (d & STAT_nExtract) ? "ext":"EXT", (d & STAT_Empty0) ? 1:0, (d & STAT_Empty1) ? 1:0, (d & STAT_Empty2) ? 1:0, (d & STAT_Empty3) ? 1:0); d0 = d; } if (kbhit()) { c = getch(); if (c!='r' && c!='R') break; printf("Pulsing Global Reset signal.\n"); outportb(ioPort+OUT_Reset, 0); } } if (c==27) exit(0); return c; } /* Write a 16-bit word somewhere in the selected shared memory area ** (either D000 or E000 segment) */ void writeMem8(unsigned char val) { static unsigned int offset; unsigned char far *memptr; memptr = MK_FP(page_E ? 0xE000:0xD000, offset); *memptr = val; offset++; /* 16-bit int causes segment wraparound */ } unsigned int readMem16() { static unsigned int offset; unsigned int far *memptr; /* ensure word-alignment */ if (offset&1) offset = 0; memptr = MK_FP(page_E ? 0xE000:0xD000, offset); offset += 2; /* 16-bit int causes segment wraparound */ return *memptr; }