📄 getput.c
字号:
* Go on to the next value, if there are any more. */ count -= 1; if (count == 0) { break; } if (isReg) { address += length / 4; if (address >= TOTAL_REGS) { break; } } else { address += length; if (ADDR_TO_INDEX(address) >= machPtr->numWords) { break; } } *p = '\n'; p++; } return TCL_OK;}/* *---------------------------------------------------------------------- * * Gp_PutCmd -- * * This procedure is invoked to process the "put" Tcl command. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */intGp_PutCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */{ DLX *machPtr = (DLX *) clientData; unsigned int address; int isReg, value, result; char *end; if (argc != 3) { sprintf(interp->result, "wrong # args: should be \"%.50s location value\"", argv[0]); return TCL_ERROR; } result = GetAddress(machPtr, argv[1], &address, &isReg); if (result != TCL_OK) { return result; } result = Sym_EvalExpr(machPtr, (char *) NULL, argv[2], 0, &value, &end); if (result != TCL_OK) { return result; } if (*end != 0) { sprintf(interp->result, "bad value \"%.50s\" in \"%.50s\" command", argv[2], argv[0]); return TCL_ERROR; } if (isReg) { if (address == 0) { sprintf(interp->result, "can't modify %s", Asm_RegNames[address]); return TCL_ERROR; } if ((address == PC_REG) || (address == NEXT_PC_REG)) { if (value & 0x3) { sprintf(interp->result, "address 0x%x not properly aligned for pc or npc", value); return TCL_ERROR; } value = ADDR_TO_INDEX(value); } machPtr->regs[address] = value; } else { if (ADDR_TO_INDEX(address) < machPtr->numWords) { MemWord *wordPtr; wordPtr = &machPtr->memPtr[ADDR_TO_INDEX(address)]; wordPtr->value = value; wordPtr->opCode = OP_NOT_COMPILED; } else if (Io_Write(machPtr, (address & ~0x3), value, 4) == 0) { sprintf(interp->result, "location \"%.50s\" doesn't exist in memory", argv[1]); return TCL_ERROR; } } return TCL_OK;}/* *---------------------------------------------------------------------- * * Gp_FPutCmd -- * * This procedure is invoked to process the "fput" Tcl command. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */intGp_FPutCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */{ DLX *machPtr = (DLX *) clientData; unsigned int address; int isReg, result, value[2]; float *pf = (float *)&(value[0]); double *pd = (double *)&(value[0]), atof(); enum {FLOAT, DOUBLE} format = FLOAT; if ((argc != 3) && (argc != 4)) { sprintf(interp->result, "wrong # args: should be \"%.50s location value [f|d]\"", argv[0]); return TCL_ERROR; } result = GetAddress(machPtr, argv[1], &address, &isReg); if (result != TCL_OK) { return result; } if (argc == 4) { if (*argv[3] == 'f') format = FLOAT; else if (*argv[3] == 'd') format = DOUBLE; else { sprintf(interp->result, "invalid type flag, must be f or d"); return TCL_ERROR; } } if (!isReg) { address = address & ~3; } else if (format == FLOAT) { if (address > 63) { sprintf(interp->result, "illegal register"); return TCL_ERROR; } } else { /* format == DOUBLE */ if ((address < 32) || (address > 63) || (address %2)) { sprintf(interp->result, "illegal register for double"); return TCL_ERROR; } } if (format == FLOAT) { *pf = atof(argv[2]); } else { /* format == DOUBLE */ *pd = atof(argv[2]); } if (isReg) { if (address == 0) { sprintf(interp->result, "can't modify %s", Asm_RegNames[address]); return TCL_ERROR; } machPtr->regs[address] = value[0]; if (format == DOUBLE) { machPtr->regs[address+1] = value[1]; } } else { if (ADDR_TO_INDEX(address) < machPtr->numWords) { MemWord *wordPtr; wordPtr = &machPtr->memPtr[ADDR_TO_INDEX(address)]; wordPtr->value = value[0]; wordPtr->opCode = OP_NOT_COMPILED; if (format == DOUBLE) { wordPtr = &machPtr->memPtr[ADDR_TO_INDEX(address+4)]; wordPtr->value = value[1]; wordPtr->opCode = OP_NOT_COMPILED; } } else if (Io_Write(machPtr, (address & ~0x3), value[0], 4) == 0) { sprintf(interp->result, "location \"%.50s\" doesn't exist in memory", argv[1]); return TCL_ERROR; } } return TCL_OK;}/* *---------------------------------------------------------------------- * * GetAddress -- * * Convert a string to information about an address, suitable for * reading or writing the location. * * Results: * Returns a standard Tcl result. * * Side effects: * Generates an error in interp if string can't be parsed into * an address. * *---------------------------------------------------------------------- */static intGetAddress(machPtr, string, addressPtr, regPtr) DLX *machPtr; /* Machine address will be used with. * Also used for error reporting. */ char *string; /* Specification of address. */ unsigned int *addressPtr; /* Store address of value here. */ int *regPtr; /* Store 1 here if address refers to * a register, 0 for memory location. */{ unsigned int result; char *end; result = Sym_GetSym(machPtr, (char *) NULL, string, SYM_PSEUDO_OK, addressPtr); if (result == SYM_FREG_FOUND) { *regPtr = 1; *addressPtr += 32; return TCL_OK; } if (result == SYM_REGISTER) { *regPtr = 1; return TCL_OK; } if (result == SYM_FOUND) { *regPtr = 0; return TCL_OK; } result = Sym_EvalExpr(machPtr, (char *) NULL, string, 0, (int *) addressPtr, &end); if (result != TCL_OK) { return result; } if (*end != 0) { sprintf(machPtr->interp->result, "mistyped expression \"%.50s\"", string); return TCL_ERROR; } *regPtr = 0; return TCL_OK;}/* *---------------------------------------------------------------------- * * GetString -- * * Given an address, return the ASCII string at that address. * * Results: * The return value is a pointer to ASCII string that's at * "address" in machPtr's memory. The integer at *countPtr * is overwritten with the number of bytes in the string, * including the terminating NULL character. If the string * is very long, the return value may be truncated to hold only * the first few characters of the string (*countPtr will also * be truncated). The return value is stored in a static buffer * that will be overwritten on the next call to this procedure. * * Side effects: * None. * *---------------------------------------------------------------------- */static char *GetString(machPtr, address, countPtr) register DLX *machPtr; /* Machine whose memory is to be examined. */ unsigned int address; /* Address of string. */ int *countPtr; /* Fill in string length (including NULL * character, if any) here. */{#define MAX_LENGTH 200 static char buffer[(4*MAX_LENGTH)+20]; char *p; unsigned int index; int value, count; buffer[0] = '"'; p = buffer+1; for (count = 0; ; count++, address++) { index = ADDR_TO_INDEX(address); if (index >= machPtr->numWords) { break; } value = machPtr->memPtr[index].value; switch (address & 0x3) { case 0: value >>= 24; break; case 1: value >>= 16; break; case 2: value >>= 8; break; } value &= 0xff; if (value == 0) { *countPtr = count+1; break; } if (count == MAX_LENGTH) { *countPtr = MAX_LENGTH; strcpy(p, "..."); p += 3; break; } if (value == '\\') { strcpy(p, "\\\\"); p += 2; } else if (value == '"') { strcpy(p, "\\\""); p += 2; } else if (isascii(value) && isprint(value)) { *p = value; p++; } else if (value == '\n') { strcpy(p, "\\n"); p += 2; } else if (value == '\t') { strcpy(p, "\\t"); p += 2; } else if (value == '\b') { strcpy(p, "\\b"); p += 2; } else if (value == '\r') { strcpy(p, "\\r"); p += 2; } else { sprintf(p, "\\x%02x", value); p += 4; } } *p = '"'; p[1] = 0; return buffer;}/* *---------------------------------------------------------------------- * * Gp_PutString -- * * Given an ASCII string, store it in the memory of a machine. * * Results: * The return value is the number of bytes actually stored * in machPtr's memory. If endPtr isn't NULL, *endPtr is * filled in with the address of the character that terminated * the string (either term or 0). * * Side effects: * The bytes of "string" are stored in machPtr's memory starting * at "address". Standard Tcl backslash sequences are interpreted. * *---------------------------------------------------------------------- */intGp_PutString(machPtr, string, term, address, addNull, endPtr) register DLX *machPtr; /* Machine whose memory is to * be modified. */ register char *string; /* String to store. */ char term; /* Character that terminates string. */ unsigned int address; /* Where in machPtr's memory to store.*/ int addNull; /* If non-zero, add a terminating * NULL character to memory after * the string. */ char **endPtr; /* If non-NULL, fill in with address * of terminating character. */{ int backslashCount; int size; size = 0; while (1) { if (*string == '\\') { Gp_PutByte(machPtr, address, Tcl_Backslash(string, &backslashCount)); string += backslashCount; } else if ((*string == 0) || (*string == term)) { break; } else { Gp_PutByte(machPtr, address, *string); string++; } address += 1; size += 1; } if (addNull) { Gp_PutByte(machPtr, address, 0); size += 1; } if (endPtr != 0) { *endPtr = string; } return size;}/* *---------------------------------------------------------------------- * * Gp_PutByte -- * * Store a particular byte at a particular address in memory. * * Results: * None. * * Side effects: * MachPtr's memory gets modified. * *---------------------------------------------------------------------- */voidGp_PutByte(machPtr, address, value) register DLX *machPtr; /* Machine whose memory to modify. */ unsigned int address; /* Where to store value. */ int value; /* Value to store as byte at address. */{ MemWord *wordPtr; int index; char msg[20], start[20], end[20]; index = ADDR_TO_INDEX(address); if (index < machPtr->numWords) { wordPtr = &machPtr->memPtr[index]; switch (address & 0x3) { case 0: wordPtr->value = (wordPtr->value & 0xffffff) | (value << 24); break; case 1: wordPtr->value = (wordPtr->value & 0xff00ffff) | ((value << 16) & 0xff0000); break; case 2: wordPtr->value = (wordPtr->value & 0xffff00ff) | ((value << 8) & 0xff00); break; case 3: wordPtr->value = (wordPtr->value & 0xffffff00) | (value & 0xff); break; }/* sprintf(msg, "%08x; ", wordPtr->value); sprintf(start, "%d.%d ", 1+index/4, 20+index%4*15); sprintf(end, "%d.%d; ", 1+index/4, 28+index%4*15); Tcl_VarEval(machPtr->interp, ".data.t delete ", start, end, ".data.t insert ", start, msg, ".data.t yview ", start, (char *)NULL); */ wordPtr->opCode = OP_NOT_COMPILED; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -