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);
}
Example #3
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;
}