/** * 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, §or); 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(); } }
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, §or); 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"); } }