bool SetMemory(int value, U16 size, long count, long offset, U16 handle) { // value is the value to set memory to // offset is the number of units from the start of allocated memory // size is the size of the unit, count is the number of units to set // Returns true if successful, false if failure BYTE diskbuf[DISKWRITELEN]; long start; // first location to set long tomove; // number of bytes to set U16 numwritten; start = (long)offset * size; tomove = (long)count * size; if (debugflag == debug_flags::display_memory_statistics) if (CheckBounds(start, tomove, handle)) return false; // out of bounds, don't do it bool success = false; switch (handletable[handle].Nowhere.stored_at) { case NOWHERE: // SetMemory DisplayHandle(handle); break; case MEMORY: // SetMemory for (int i = 0; i < size; i++) { memset(handletable[handle].Linearmem.memory+start, value, (U16)count); start += count; } success = true; // No way to gauge success or failure break; case DISK: // SetMemory memset(diskbuf, value, (U16)DISKWRITELEN); rewind(handletable[handle].Disk.file); fseek(handletable[handle].Disk.file, start, SEEK_SET); while (tomove > DISKWRITELEN) { numwritten = (U16)write1(diskbuf, (U16)DISKWRITELEN, 1, handletable[handle].Disk.file); if (numwritten != 1) { WhichDiskError(2); goto diskerror; } tomove -= DISKWRITELEN; } numwritten = (U16)write1(diskbuf, (U16)tomove, 1, handletable[handle].Disk.file); if (numwritten != 1) { WhichDiskError(2); break; } success = true; diskerror: break; } // end of switch if (!success && debugflag == debug_flags::display_memory_statistics) DisplayHandle(handle); return success; }
static int CheckBounds(long start, long length, U16 handle) { if (handletable[handle].Nowhere.size - start - length < 0) { stopmsg(STOPMSG_INFO_ONLY | STOPMSG_NO_BUZZER, "Memory reference out of bounds."); DisplayHandle(handle); return (1); } if (length > (long)USHRT_MAX) { stopmsg(STOPMSG_INFO_ONLY | STOPMSG_NO_BUZZER, "Tried to move > 65,535 bytes."); DisplayHandle(handle); return (1); } if (handletable[handle].Nowhere.stored_at == DISK && (stackavail() <= DISKWRITELEN)) { stopmsg(STOPMSG_INFO_ONLY | STOPMSG_NO_BUZZER, "Stack space insufficient for disk memory."); DisplayHandle(handle); return (1); } if (length <= 0) { stopmsg(STOPMSG_INFO_ONLY | STOPMSG_NO_BUZZER, "Zero or negative length."); DisplayHandle(handle); return (1); } if (start < 0) { stopmsg(STOPMSG_INFO_ONLY | STOPMSG_NO_BUZZER, "Negative offset."); DisplayHandle(handle); return (1); } return (0); }
int DdmTestConsole::DisplayHandles(int _ConnectionID, char *pCommandLine) { int displayMask = 0x0; char *pCurrent = pCommandLine; int iCurrent; char *pArg; char *pRest; int rulenum, tempi, pos; // trim whitespace off front for (pos=0; pos < (int)strlen(pCommandLine); pos++) { if (pCommandLine[pos] == ' ') pCurrent++; else break; } // and back for (iCurrent = strlen(pCurrent); iCurrent > 0; iCurrent--) { if (pCurrent[iCurrent-1] != ' ') break; } // If we didn't get any arguments, display all the handles if (iCurrent == 0) { displayMask = 0xFFFFFFFF; } // If we got a digit, we must be requesting individual handles else if (isdigit(pCurrent[0])) { SplitCommand(pCurrent, pArg, pRest); while (pArg[0] != 0) { int handlenum = atoi(pArg); if (handlenum < HandleMan->numHandles) { WriteString(_ConnectionID, "\n\rHandle Information:\n\r\0"); DisplayHandle(_ConnectionID, handlenum); } else { WriteString(_ConnectionID, "\n\rInvalid handle specified\n\r\0"); } pCurrent = pRest; SplitCommand(pCurrent, pArg, pRest); } return 0; } // else I guess we must want to mask the entire list else { SplitCommand(pCurrent, pArg, pRest); while (pArg[0] != 0) { if (!strcmp(pArg, "running")) displayMask = displayMask |= Running; else if (!strcmp(pArg, "finished")) displayMask = displayMask |= Finished; else if (!strcmp(pArg, "error")) displayMask = displayMask |= Error; pCurrent = pRest; SplitCommand(pCurrent, pArg, pRest); } // if we didn't recognize any masks, it must have been a typo - display them all if (displayMask == 0x0) displayMask = 0xFFFFFFFF; } WriteString(_ConnectionID, "\n\rHandle List:\n\r\0"); for(int i=0; i < HandleMan->numHandles; i++) { DisplayHandle(_ConnectionID, i, displayMask); } return 0; }
bool MoveFromMemory(BYTE *buffer, U16 size, long count, long offset, U16 handle) { // buffer points is the location to move the data to // offset is the number of units from the beginning of buffer to start moving // size is the size of the unit, count is the number of units to move // Returns true if successful, false if failure BYTE diskbuf[DISKWRITELEN]; long start; // first location to move long tomove; // number of bytes to move U16 numread; start = (long)offset * size; tomove = (long)count * size; if (debugflag == debug_flags::display_memory_statistics) if (CheckBounds(start, tomove, handle)) return false; // out of bounds, don't do it bool success = false; switch (handletable[handle].Nowhere.stored_at) { case NOWHERE: // MoveFromMemory DisplayHandle(handle); break; case MEMORY: // MoveFromMemory for (int i = 0; i < size; i++) { memcpy(buffer, handletable[handle].Linearmem.memory+start, (U16)count); start += count; buffer += count; } success = true; // No way to gauge success or failure break; case DISK: // MoveFromMemory rewind(handletable[handle].Disk.file); fseek(handletable[handle].Disk.file, start, SEEK_SET); while (tomove > DISKWRITELEN) { numread = (U16)fread(diskbuf, (U16)DISKWRITELEN, 1, handletable[handle].Disk.file); if (numread != 1 && !feof(handletable[handle].Disk.file)) { WhichDiskError(4); goto diskerror; } memcpy(buffer, diskbuf, (U16)DISKWRITELEN); tomove -= DISKWRITELEN; buffer += DISKWRITELEN; } numread = (U16)fread(diskbuf, (U16)tomove, 1, handletable[handle].Disk.file); if (numread != 1 && !feof(handletable[handle].Disk.file)) { WhichDiskError(4); break; } memcpy(buffer, diskbuf, (U16)tomove); success = true; diskerror: break; } // end of switch if (!success && debugflag == debug_flags::display_memory_statistics) DisplayHandle(handle); return success; }
bool MoveToMemory(BYTE *buffer, U16 size, long count, long offset, U16 handle) { // buffer is a pointer to local memory // Always start moving from the beginning of buffer // offset is the number of units from the start of the allocated "Memory" // to start moving the contents of buffer to // size is the size of the unit, count is the number of units to move // Returns true if successful, false if failure BYTE diskbuf[DISKWRITELEN]; long start; // offset to first location to move to long tomove; // number of bytes to move U16 numwritten; start = (long)offset * size; tomove = (long)count * size; if (debugflag == debug_flags::display_memory_statistics) if (CheckBounds(start, tomove, handle)) return false; // out of bounds, don't do it bool success = false; switch (handletable[handle].Nowhere.stored_at) { case NOWHERE: // MoveToMemory DisplayHandle(handle); break; case MEMORY: // MoveToMemory #if defined(_WIN32) _ASSERTE(handletable[handle].Linearmem.size >= size*count + start); #endif memcpy(handletable[handle].Linearmem.memory + start, buffer, size*count); success = true; // No way to gauge success or failure break; case DISK: // MoveToMemory rewind(handletable[handle].Disk.file); fseek(handletable[handle].Disk.file, start, SEEK_SET); while (tomove > DISKWRITELEN) { memcpy(diskbuf, buffer, (U16)DISKWRITELEN); numwritten = (U16)write1(diskbuf, (U16)DISKWRITELEN, 1, handletable[handle].Disk.file); if (numwritten != 1) { WhichDiskError(3); goto diskerror; } tomove -= DISKWRITELEN; buffer += DISKWRITELEN; } memcpy(diskbuf, buffer, (U16)tomove); numwritten = (U16)write1(diskbuf, (U16)tomove, 1, handletable[handle].Disk.file); if (numwritten != 1) { WhichDiskError(3); break; } success = true; diskerror: break; } // end of switch if (!success && debugflag == debug_flags::display_memory_statistics) DisplayHandle(handle); return success; }
U16 MemoryAlloc(U16 size, long count, int stored_at) { // Returns handle number if successful, 0 or nullptr if failure U16 handle = 0; int use_this_type; long toallocate; toallocate = count * size; if (toallocate <= 0) // we failed, can't allocate > 2,147,483,647 return 0U; // or it wraps around to negative /* check structure for requested memory type (add em up) to see if sufficient amount is available to grant request */ use_this_type = check_for_mem(stored_at, toallocate); if (use_this_type == NOWHERE) { DisplayError(stored_at, toallocate); goodbye(); } // get next available handle handle = next_handle(); if (handle >= MAXHANDLES || handle == 0) { DisplayHandle(handle); return 0U; // Oops, do something about this! ????? } // attempt to allocate requested memory type bool success = false; switch (use_this_type) { default: case NOWHERE: // MemoryAlloc use_this_type = NOWHERE; // in case nonsense value is passed break; case MEMORY: // MemoryAlloc // Availability of memory checked in check_for_mem() handletable[handle].Linearmem.memory = (BYTE *)malloc(toallocate); handletable[handle].Linearmem.size = toallocate; handletable[handle].Linearmem.stored_at = MEMORY; numTOTALhandles++; success = true; break; case DISK: // MemoryAlloc memfile[9] = (char)(handle % 10 + (int)'0'); memfile[8] = (char)((handle % 100) / 10 + (int)'0'); memfile[7] = (char)((handle % 1000) / 100 + (int)'0'); if (disktarga) handletable[handle].Disk.file = dir_fopen(workdir, light_name, "a+b"); else handletable[handle].Disk.file = dir_fopen(tempdir, memfile, "w+b"); rewind(handletable[handle].Disk.file); if (fseek(handletable[handle].Disk.file, toallocate, SEEK_SET) != 0) handletable[handle].Disk.file = nullptr; if (handletable[handle].Disk.file == nullptr) { handletable[handle].Disk.stored_at = NOWHERE; use_this_type = NOWHERE; WhichDiskError(1); DisplayMemory(); driver_buzzer(buzzer_codes::PROBLEM); break; } numTOTALhandles++; success = true; fclose(handletable[handle].Disk.file); // so clusters aren't lost if we crash while running if (disktarga) handletable[handle].Disk.file = dir_fopen(workdir, light_name, "r+b"); else handletable[handle].Disk.file = dir_fopen(tempdir, memfile, "r+b"); // reopen rewind(handletable[handle].Disk.file); handletable[handle].Disk.size = toallocate; handletable[handle].Disk.stored_at = DISK; use_this_type = DISK; break; } // end of switch if (stored_at != use_this_type && debugflag == debug_flags::display_memory_statistics) { char buf[MSGLEN]; sprintf(buf, "Asked for %s, allocated %lu bytes of %s, handle = %u.", memstr[stored_at], toallocate, memstr[use_this_type], handle); stopmsg(STOPMSG_INFO_ONLY | STOPMSG_NO_BUZZER, (char *)buf); DisplayMemory(); } if (success) return (handle); else // return 0 if failure return 0U; }