|
|
1.1 ! root 1: /* $Header: dl.c,v 10.3 86/02/01 15:46:40 tony Rel $ */ ! 2: /* dl.c downloads code into the vs100. Routines are ! 3: * ! 4: * DownLoad Determines device version and downloads firmware ! 5: * ! 6: * Takes an int which is the device to download and ! 7: * returns 0 if everything went well and -1 if ! 8: * there is some problem. ! 9: * ! 10: */ ! 11: ! 12: /**************************************************************************** ! 13: * * ! 14: * Copyright (c) 1983, 1984 by * ! 15: * DIGITAL EQUIPMENT CORPORATION, Maynard, Massachusetts. * ! 16: * All rights reserved. * ! 17: * * ! 18: * This software is furnished on an as-is basis and may be used and copied * ! 19: * only with inclusion of the above copyright notice. This software or any * ! 20: * other copies thereof may be provided or otherwise made available to * ! 21: * others only for non-commercial purposes. No title to or ownership of * ! 22: * the software is hereby transferred. * ! 23: * * ! 24: * The information in this software is subject to change without notice * ! 25: * and should not be construed as a commitment by DIGITAL EQUIPMENT * ! 26: * CORPORATION. * ! 27: * * ! 28: * DIGITAL assumes no responsibility for the use or reliability of its * ! 29: * software on equipment which is not supplied by DIGITAL. * ! 30: * * ! 31: * * ! 32: ****************************************************************************/ ! 33: ! 34: #include "vs100.h" ! 35: #include <sys/ioctl.h> ! 36: #include "vsioctl.h" ! 37: #include "vssite.h" ! 38: ! 39: #define CODE_START_ADDRESS 0x1000 ! 40: ! 41: #define BUFSIZE 512 /* Why not? Everyone uses 512 */ ! 42: ! 43: int HexArray[128]; ! 44: #define Hex2(p) ((HexArray[*(p)]<<4)+HexArray[*((p)+1)]) ! 45: ! 46: extern int vsdev; /* File number of the workstation */ ! 47: BitMap screen; /* The actual screen memory */ ! 48: ! 49: /* Determine what version of the vs we have and download the appropriate ! 50: * firmware. Determining the version is not trivial and as versions change ! 51: * this may also have to change. ! 52: */ ! 53: ! 54: int DownLoad () ! 55: { ! 56: FILE *fopen(), *fd; /* The file descriptor */ ! 57: char *AllocateSpace(); ! 58: char *filename; /* Name of download file */ ! 59: char *buf; /* The input buffer */ ! 60: char inline[BUFSIZE]; /* The line from the file */ ! 61: int bufpos; /* The current position in the buffer */ ! 62: int linesize; /* The number of bytes represented by a line */ ! 63: int lineaddr; /* The intended address of the line */ ! 64: int nextaddr; /* The expected next address */ ! 65: int destaddr; /* The destination for the current buffer */ ! 66: caddr_t pMem; /* Program memory pointer */ ! 67: caddr_t startAddr; /* Address to start microcode */ ! 68: MemArea programMemory; /* Information about program memory */ ! 69: char textVersion[5]; /* The version number reported back */ ! 70: int version; ! 71: char errmessage[BUFSIZE]; /* error message buffer */ ! 72: ! 73: /* Initialize the device, ! 74: * figure out just what version of the device we have, and ! 75: * get the address to load the code into ! 76: */ ! 77: ! 78: if (PacketInit() || ! 79: ioctl (vsdev, (int) VSIOINIT, (caddr_t) NULL) || ! 80: ioctl (vsdev, (int) VSIOGETVER, (caddr_t) &version) || ! 81: ReportStatus ((int *) textVersion, (short *) NULL, (short *) NULL, ! 82: &screen, (MemArea *) NULL, &programMemory, ! 83: (MemArea *) NULL, 1)) { ! 84: VSError (); ! 85: return(-1); ! 86: } ! 87: ! 88: switch (version) { ! 89: case 8: ! 90: ! 91: /* Everyone in the world reports 8! Fortunately I can ! 92: tell them apart by other means (Then why isn't that ! 93: the version??? You tell me!) */ ! 94: ! 95: if (screen.bm_height != 800) filename = LOAD_FILE_3_8; ! 96: else filename = LOAD_FILE_2B; ! 97: break; ! 98: ! 99: case 1: /* This is an SBO, I think! */ ! 100: filename = LOAD_FILE_SBO; ! 101: break; ! 102: ! 103: default: ! 104: ! 105: /* Assume we have a 3.10. We may even be right */ ! 106: ! 107: filename = LOAD_FILE_3_10; ! 108: break; ! 109: } ! 110: ! 111: pMem = *(caddr_t *) programMemory.m_base; ! 112: startAddr = pMem + CODE_START_ADDRESS; ! 113: ! 114: /* Open the file in read mode */ ! 115: ! 116: if ((fd = fopen (filename, "r")) == NULL) { ! 117: sprintf(errmessage, "Xvs100: Can't open uCode file %s.\n", ! 118: filename); ! 119: DeviceError(errmessage); ! 120: return (-1); ! 121: } ! 122: ! 123: InitHexArray(); ! 124: ! 125: /* Read in the s-line file and copy to the workstation */ ! 126: ! 127: bufpos = 0; ! 128: buf = AllocateSpace (BUFSIZE); ! 129: destaddr = 0; ! 130: ! 131: while (fgets (inline, BUFSIZE, fd) != NULL) { ! 132: if (inline[0] == '\n') continue; ! 133: if (ParseLine (inline, &linesize, &lineaddr)) break; ! 134: if (destaddr == 0) destaddr = nextaddr = lineaddr; ! 135: if (bufpos > 0 && ! 136: (lineaddr != nextaddr || linesize + bufpos > BUFSIZE)) { ! 137: if (MoveObjectDownRom (buf, pMem + destaddr, bufpos)) ! 138: return (-1); ! 139: buf = AllocateSpace (BUFSIZE); ! 140: bufpos = 0; ! 141: destaddr = nextaddr = lineaddr; ! 142: } ! 143: CopyLine (inline, buf, linesize, bufpos); ! 144: bufpos += linesize; ! 145: nextaddr += linesize; ! 146: } ! 147: ! 148: /* Copy the last packet */ ! 149: ! 150: if (bufpos > 0) { ! 151: if (MoveObjectDownRom (buf, pMem + destaddr, bufpos)) ! 152: return (-1); ! 153: } ! 154: ! 155: fclose (fd); ! 156: ! 157: /* Sync the writes to make sure it's all been downloaded! */ ! 158: ! 159: if (SynchWrites()) return (-1); ! 160: ! 161: /* Start microcode */ ! 162: ! 163: if (ioctl (vsdev, (int) VSIOSTART, (caddr_t) &startAddr)) return (-1); ! 164: ! 165: return (VSMemInit()); /* Initialize memory allocator */ ! 166: } ! 167: ! 168: /* The following routines parse the so-called s-line format. This was ! 169: * lifted more or less verbatim from the vms software; I don't fully ! 170: * understand it and you certainly don't want to even bother trying. ! 171: */ ! 172: ! 173: ParseLine (line, linesize, lineaddr) ! 174: char *line; ! 175: int *linesize, *lineaddr; ! 176: { ! 177: if (line[0] != 'S') DLError ("Invalid format", line); ! 178: ! 179: switch (line[1]) { ! 180: case '0': ! 181: break; ! 182: case '1': case '2': ! 183: #ifdef notdef ! 184: CheckLine (line); /* Checks checksum */ ! 185: #endif ! 186: if (line[1] == '1') { ! 187: *linesize = Hex2(line+2) - 3; ! 188: *lineaddr = Hex (line+4, 4); ! 189: } else { ! 190: *linesize = Hex2(line+2) - 4; ! 191: *lineaddr = Hex (line+4, 6); ! 192: } ! 193: break; ! 194: case '9': ! 195: return (-1); ! 196: default: ! 197: DLError ("Invalid format", line); ! 198: break; ! 199: } ! 200: return (0); ! 201: } ! 202: ! 203: CopyLine (line, buffer, count, pos) ! 204: char *line, *buffer; ! 205: register int count, pos; ! 206: { ! 207: register char *start; ! 208: ! 209: if (line[1] == '1') start = line + 8; ! 210: else start = line + 10; ! 211: ! 212: while (--count >= 0) { ! 213: buffer[pos^1] = Hex2(start); ! 214: pos++; ! 215: start += 2; ! 216: } ! 217: } ! 218: ! 219: CheckLine (line) ! 220: register char *line; ! 221: { ! 222: register char *lp; ! 223: register int count; ! 224: register char checksum; ! 225: ! 226: lp = line + 2; ! 227: count = Hex2(lp); ! 228: checksum = 0; ! 229: ! 230: do { ! 231: checksum += Hex2(lp); ! 232: lp += 2; ! 233: } while (--count >= 0); ! 234: ! 235: if (checksum != 0xff) DLError ("Bad checksum", line); ! 236: } ! 237: ! 238: InitHexArray () ! 239: { ! 240: register char c; ! 241: for (c = 'A'; c <= 'F'; c++) HexArray[c] = c - 'A' + 10; ! 242: for (c = 'a'; c <= 'f'; c++) HexArray[c] = c - 'a' + 10; ! 243: for (c= '0'; c <= '9'; c++) HexArray[c] = c - '0'; ! 244: } ! 245: ! 246: int Hex (cp, n) ! 247: register char *cp; ! 248: register int n; ! 249: { ! 250: register int i = 0; ! 251: while (--n >= 0) ! 252: i = (i<<4) + HexArray[*cp++]; ! 253: return (i); ! 254: } ! 255: ! 256: DLError (str1, str2) ! 257: char *str1, *str2; ! 258: { ! 259: fprintf (stderr, "Downloader: %s: %s\n", str1, str2); ! 260: fflush (stderr); ! 261: exit (1); ! 262: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.