/**
 * Read data from the specific position indicated by the disk id and sector id.
 * @param disk_id: Indicates which disk to read from. 
 * @param sector: Indicates which sector to read from. 
 * @param buffer: The buffer to hold the data.
 */
void os_disk_read(INT32 disk_id, INT32 sector, char *buffer)
{
    INT32 status;
    int result;

    write_to_memory(Z502DiskSetID, &disk_id);
    read_from_memory(Z502DiskStatus, &status);
    // Disk hasn't been used - should be free
    if (status == DEVICE_FREE)
    {
        write_to_memory(Z502DiskSetSector, &sector);
        write_to_memory(Z502DiskSetBuffer, (INT32 *) buffer);
        status = 0; // Specify a read
        write_to_memory(Z502DiskSetAction, &status);
        status = 0; // Must be set to 0
        write_to_memory(Z502DiskStart, &status);

        CurrentPCB->disk_id = disk_id;
        CurrentPCB->operation = -1;

        get_data_lock(SUSPEND_QUEUE_LOCK);
        result = add_to_suspend_queue(CurrentPCB);
        release_data_lock(SUSPEND_QUEUE_LOCK);
        if (result)
        {
            CurrentPCB->suspend = TRUE;
            print_scheduling_info(ACTION_NAME_READ, CurrentPCB, NORMAL_INFO);
        }
        else
        {
            error_message("add_to_suspend_queue");
            shut_down();
        }
        os_dispatcher();
    }
    else if (status == DEVICE_IN_USE)
    {
        CurrentPCB->disk_id = disk_id;
        CurrentPCB->operation = READ_ONE;
        CurrentPCB->disk = disk_id;
        CurrentPCB->sector = sector;
        CurrentPCB->disk_data = (DISK_DATA *) buffer;

        get_data_lock(SUSPEND_QUEUE_LOCK);
        result = add_to_suspend_queue(CurrentPCB);
        release_data_lock(SUSPEND_QUEUE_LOCK);
        if (result)
        {
            CurrentPCB->suspend = TRUE;
            print_scheduling_info(ACTION_NAME_READ, CurrentPCB, NORMAL_INFO);
        }
        else
        {
            error_message("add_to_suspend_queue");
            shut_down();
        }
        os_dispatcher();
    }
}
Exemple #2
0
char *dpth_mk(struct dpth *dpth)
{
	static char save_path[32];
	static struct lock *lock=NULL;
	while(1)
	{
		snprintf(save_path, sizeof(save_path), "%04X/%04X/%04X/%04X",
			dpth->prim, dpth->seco, dpth->tert, dpth->sig);
		if(!dpth->need_data_lock) return save_path;

		if(!lock && !(lock=lock_alloc())) goto error;
		if(get_data_lock(lock, dpth, save_path)) goto error;
		switch(lock->status)
		{
			case GET_LOCK_GOT: break;
			case GET_LOCK_NOT_GOT:
				// Increment and try again.
				if(dpth_incr(dpth)) goto error;
				continue;
			case GET_LOCK_ERROR:
			default:
				goto error;
		}

		dpth->need_data_lock=0; // Got it.
		if(add_lock_to_list(dpth, lock, save_path)) goto error;
		lock=NULL;
		return save_path;
	}
error:
	lock_free(&lock);
	return NULL;
}
/**
 * Write data into the specific position indicated by the disk id and sector id.
 * @param disk_id: Indicates which disk to write to. 
 * @param sector: Indicates which sector to write to. 
 * @param buffer: The data needs to be written.
 */
void os_disk_write(INT32 disk_id, INT32 sector, char *buffer)
{
    INT32 status;
    int result;

    /* Do the hardware call to put data on disk */
    write_to_memory(Z502DiskSetID, &disk_id);
    read_from_memory(Z502DiskStatus, &status);

    // If the disk is free, indicates success in writing.
    if (status == DEVICE_FREE)
    {
        write_to_memory(Z502DiskSetSector, &sector);
        write_to_memory(Z502DiskSetBuffer, (INT32 *) buffer);
        status = 1; // Specify a write
        write_to_memory(Z502DiskSetAction, &status);
        status = 0; // Must be set to 0
        write_to_memory(Z502DiskStart, &status);

        CurrentPCB->disk_id = disk_id;
        CurrentPCB->operation = -1;

        get_data_lock(SUSPEND_QUEUE_LOCK);
        result = add_to_suspend_queue(CurrentPCB);
        release_data_lock(SUSPEND_QUEUE_LOCK);
        if (result)
        {
            CurrentPCB->suspend = TRUE;
            print_scheduling_info(ACTION_NAME_SUSPEND, CurrentPCB, NORMAL_INFO);
        }
        else
        {
            error_message("add_to_suspend_queue");
            shut_down();
        }
        os_dispatcher();
        return;
    }
    // If the disk is busy, indicates failure in writing.
    else if (status == DEVICE_IN_USE)
    {
        DISK_DATA *disk_data;
        disk_data = (DISK_DATA *) calloc(1, sizeof ( DISK_DATA));

        CurrentPCB->disk_id = disk_id;
        CurrentPCB->operation = WRITE_ONE;
        CurrentPCB->disk = disk_id;
        CurrentPCB->sector = sector;
        memcpy(disk_data, buffer, sizeof (DISK_DATA));
        CurrentPCB->disk_data = disk_data;
        result = add_to_suspend_queue(CurrentPCB);
        if (result)
        {
            CurrentPCB->suspend = TRUE;
            print_scheduling_info(ACTION_NAME_WRITE, CurrentPCB, NORMAL_INFO);
        }
        else
        {
            error_message("add_to_suspend_queue");
            shut_down();
        }
        os_dispatcher();
        return;
    }
    else
    {
        printf("some error not processed in os_disk_write!\n");
    }
}