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: }