void output_char(WINDOW* wnd, unsigned char c){ volatile int saved_if; DISABLE_INTR(saved_if); short tempchar = (0x0f << 8) | c; if(c != '\n'){ poke_w(0xb8000 + ((wnd->x + wnd->cursor_x)*2) + ((wnd->y + wnd->cursor_y)*160) , tempchar); } if(wnd->cursor_x+1 >= wnd->width || c == '\n'){ if(wnd->cursor_y +1 >= wnd->height){ scroll(wnd); } else{wnd->cursor_y++;} wnd->cursor_x =0; } else{ wnd->cursor_x++; } ENABLE_INTR(saved_if); }
void clear_window(WINDOW* wnd) { int x, y; int wx, wy; volatile int flag; DISABLE_INTR (flag); wnd->cursor_x = 0; wnd->cursor_y = 0; for (y = 0; y < wnd->height; y++) { wy = wnd->y + y; for (x = 0; x < wnd->width; x++) { wx = wnd->x + x; poke_screen(wx, wy, 0); } } show_cursor(wnd); ENABLE_INTR (flag); }
void output_char(WINDOW* wnd, unsigned char c) { volatile int flag; DISABLE_INTR (flag); remove_cursor(wnd); switch (c) { case '\n': case 13: wnd->cursor_x = 0; wnd->cursor_y++; break; case '\b': if (wnd->cursor_x != 0) { wnd->cursor_x--; } else { if (wnd->cursor_y != 0) { wnd->cursor_x = wnd->width - 1; wnd->cursor_y--; } } break; default: poke_screen(wnd->x + wnd->cursor_x, wnd->y + wnd->cursor_y, (short unsigned int) c | (default_color << 8)); wnd->cursor_x++; if (wnd->cursor_x == wnd->width) { wnd->cursor_x = 0; wnd->cursor_y++; } break; } if (wnd->cursor_y == wnd->height) scroll_window(wnd); show_cursor(wnd); ENABLE_INTR (flag); }
void move_ghost(GHOST *ghost) { int x, y; WORD *cl; volatile int saved_if; DISABLE_INTR(saved_if); while (1) { x = (random() % 4) - 1; y = 0; if ((x % 2) == 0) { y = x - 1; x = 0; } if (maze[ghost->y + y][ghost->x + x] == ' ') { break; } } /* save ghost locations in maze */ /* add/remove characters from pacman_wnd directly as only 1 cursor per window */ maze[ghost->y][ghost->x] = ' '; cl = (WORD*)WINDOW_BASE_ADDR + WINDOW_OFFSET(pacman_wnd, ghost->x, ghost->y); poke_w((MEM_ADDR)cl, ' ' | 0x0F00); ghost->x += x; ghost->y += y; maze[ghost->y][ghost->x] = GHOST_CHAR; cl = (WORD*)WINDOW_BASE_ADDR + WINDOW_OFFSET(pacman_wnd, ghost->x, ghost->y); poke_w((MEM_ADDR)cl, GHOST_CHAR | 0x0F00); ENABLE_INTR(saved_if); }
void scroll_window(WINDOW* wnd) { int x, y; int wx, wy; volatile int flag; DISABLE_INTR(flag); for (y = 0; y < wnd->height - 1; y++) { wy = wnd->y + y; for (x = 0; x < wnd->width; x++) { wx = wnd->x + x; WORD ch = peek_screen(wx, wy + 1); poke_screen(wx, wy, ch); } } wy = wnd->y + wnd->height - 1; for (x = 0; x < wnd->width; x++) { wx = wnd->x + x; poke_screen(wx, wy, 0); } wnd->cursor_x = 0; wnd->cursor_y = wnd->height - 1; ENABLE_INTR(flag); }
void test_isr_1() { MEM_ADDR screen_offset_for_boot_proc = 0xb8000 + 4 * 160 + 2 * 11; volatile int flag; test_reset(); check_sum = 0; init_interrupts(); DISABLE_INTR(flag); init_idt_entry(TIMER_IRQ, timer_isr); kprintf("=== test_isr_1 === \n"); kprintf("This test will take a while.\n\n"); kprintf("Timer ISR: A\n"); kprintf("Boot proc: Z\n"); ENABLE_INTR(flag); int i; for (i = 1; i < 700000; i++) poke_b(screen_offset_for_boot_proc, peek_b(screen_offset_for_boot_proc) + 1); if (check_sum == 0) test_failed(70); }
void main() { Proc_PID pid; int i; /* * Initialize variables specific to a given kernel. * IMPORTANT: Only variable assignments and nothing else can be * done in this routine. */ Main_InitVars(); /* * Initialize machine dependent info. MUST BE CALLED HERE!!!. */ Mach_Init(); Sync_Init(); /* * Initialize the debugger. */ Dbg_Init(); /* * Initialize the system module, particularly the fact that there is an * implicit DISABLE_INTR on every processor. */ if (main_PrintInitRoutines) { Mach_MonPrintf("Calling Sys_Init().\n"); } Sys_Init(); /* * Now allow memory to be allocated by the "Vm_BootAlloc" call. Memory * can be allocated by this method until "Vm_Init" is called. After this * then the normal memory allocator must be used. */ if (main_PrintInitRoutines) { Mach_MonPrintf("Calling Vm_BootInit().\n"); } Vm_BootInit(); /* * Initialize all devices. */ if (main_PrintInitRoutines) { Mach_MonPrintf("Calling Dev_Init().\n"); } Dev_Init(); /* * Initialize the mappings of keys to call dump routines. * Must be after Dev_Init. */ if (main_DoDumpInit) { if (main_PrintInitRoutines) { Mach_MonPrintf("Calling Dump_Init().\n"); } Dump_Init(); } /* * Initialize the timer, signal, process, scheduling and synchronization * modules' data structures. */ if (main_PrintInitRoutines) { Mach_MonPrintf("Calling Proc_Init().\n"); } Proc_Init(); if (main_PrintInitRoutines) { Mach_MonPrintf("Calling Sync_LockStatInit().\n"); } Sync_LockStatInit(); if (main_PrintInitRoutines) { Mach_MonPrintf("Calling Timer_Init().\n"); } Timer_Init(); if (main_PrintInitRoutines) { Mach_MonPrintf("Calling Sig_Init().\n"); } Sig_Init(); if (main_PrintInitRoutines) { Mach_MonPrintf("Calling Sched_Init().\n"); } Sched_Init(); /* * Sys_Printfs are not allowed before this point. */ main_PanicOK++; printf("Sprite kernel: %s\n", SpriteVersion()); /* * Set up bins for the memory allocator. */ if (main_PrintInitRoutines) { Mach_MonPrintf("Calling Fs_Bin\n"); } Fs_Bin(); if (main_PrintInitRoutines) { Mach_MonPrintf("Calling Net_Bin\n"); } Net_Bin(); /* * Initialize virtual memory. After this point must use the normal * memory allocator to allocate memory. If you use Vm_BootAlloc then * will get a panic into the debugger. */ if (main_PrintInitRoutines) { Mach_MonPrintf("Calling Vm_Init\n"); } Vm_Init(); /* * malloc can be called from this point on. */ /* * Initialize the main process. Must be called before any new * processes are created. * Dependencies: Proc_InitTable, Sched_Init, Vm_Init, Mem_Init */ if (main_PrintInitRoutines) { Mach_MonPrintf("Calling Proc_InitMainProc\n"); } Proc_InitMainProc(); /* * Initialize the network and the routes. It would be nice if we * could call Net_Init earlier so that we can use the debugger earlier * but we must call Vm_Init first. VM could be changed so that we * could move the call earlier however. */ if (main_PrintInitRoutines) { Mach_MonPrintf("Calling Net_Init\n"); } Net_Init(); if (main_PrintInitRoutines) { Mach_MonPrintf("Calling Net_RouteInit\n"); } Net_RouteInit(); /* * Enable server process manager. */ if (main_PrintInitRoutines) { Mach_MonPrintf("Calling Proc_ServerInit\n"); } Proc_ServerInit(); /* * Initialize the recovery module. Do before Rpc and after Vm_Init. */ if (main_PrintInitRoutines) { Mach_MonPrintf("Calling Recov_Init\n"); } Recov_Init(); /* * Initialize the data structures for the Rpc system. This uses * Vm_RawAlloc to so it must be called after Vm_Init. * Dependencies: Timer_Init, Vm_Init, Net_Init, Recov_Init */ if (main_PrintInitRoutines) { Mach_MonPrintf("Calling Rpc_Init\n"); } Rpc_Init(); /* * Configure devices that may or may not exist. This needs to be * done after Proc_InitMainProc because the initialization routines * use SetJump which uses the proc table entry for the main process. */ if (main_PrintInitRoutines) { Mach_MonPrintf("Calling Dev_Config\n"); } Dev_Config(); /* * Initialize profiling after the timer and vm stuff is set up. * Dependencies: Timer_Init, Vm_Init */ if (main_DoProf) { Prof_Init(); } /* * Allow interrupts from now on. */ if (main_PrintInitRoutines) { Mach_MonPrintf("Enabling interrupts\n"); } ENABLE_INTR(); if (main_Debug) { DBG_CALL; } /* * Sleep for a few seconds to calibrate the idle time ticks. */ Sched_TimeTicks(); /* * Start profiling, if desired. */ if (main_DoProf) { (void) Prof_Start(); } /* * Do an initial RPC to get a boot timestamp. This allows * servers to detect when we crash and reboot. This will set the * system clock too, although rdate is usually done from user level later. */ if (main_PrintInitRoutines) { Mach_MonPrintf("Call Rpc_Start\n"); } Rpc_Start(); /* * Initialize the file system. */ if (main_PrintInitRoutines) { Mach_MonPrintf("Call Fs_Init\n"); } Fs_Init(); /* * Before starting up any more processes get a current directory * for the main process. Subsequent new procs will inherit it. */ if (main_PrintInitRoutines) { Mach_MonPrintf("Call Fs_ProcInit\n"); } Fs_ProcInit(); if (main_PrintInitRoutines) { Mach_MonPrintf("Bunch of call funcs\n"); } /* * Start the clock daemon and the routine that opens up the swap directory. */ Proc_CallFunc(Vm_Clock, (ClientData) NIL, 0); Proc_CallFunc(Vm_OpenSwapDirectory, (ClientData) NIL, 0); /* * Start the process that synchronizes the filesystem caches * with the data kept on disk. */ Proc_CallFunc(Fsutil_SyncProc, (ClientData) NIL, 0); /* * Create a few RPC server processes and the Rpc_Daemon process which * will create more server processes if needed. */ if (main_NumRpcServers > 0) { for (i=0 ; i<main_NumRpcServers ; i++) { (void) Rpc_CreateServer((int *) &pid); } } (void) Proc_NewProc((Address) Rpc_Daemon, PROC_KERNEL, FALSE, &pid, "Rpc_Daemon", FALSE); if (main_PrintInitRoutines) { Mach_MonPrintf("Creating Proc server procs\n"); } /* * Create processes to execute functions. */ (void) Proc_ServerProcCreate(FSCACHE_MAX_CLEANER_PROCS + VM_MAX_PAGE_OUT_PROCS); /* * Create a recovery process to monitor other hosts. Can't use * Proc_CallFunc's to do this because they can be used up waiting * for page faults against down servers. (Alternatively the VM * code could be fixed up to retry page faults later instead of * letting the Proc_ServerProc wait for recovery.) */ (void) Proc_NewProc((Address) Recov_Proc, PROC_KERNEL, FALSE, &pid, "Recov_Proc", FALSE); /* * Set up process migration recovery management. */ if (main_PrintInitRoutines) { Mach_MonPrintf("Calling Proc_MigInit\n"); } Proc_MigInit(); /* * Call the routine to start test kernel processes. */ if (main_PrintInitRoutines) { Mach_MonPrintf("Calling Main_HookRoutine\n"); } Main_HookRoutine(); /* * Print out the amount of memory used. */ printf("MEMORY %d bytes allocated for kernel\n", vmMemEnd - mach_KernStart); /* * Start up the first user process. */ if (main_PrintInitRoutines) { Mach_MonPrintf("Creating Init\n"); } (void) Proc_NewProc((Address) Init, PROC_KERNEL, FALSE, &pid, "Init", FALSE); (void) Sync_WaitTime(time_OneYear); printf("Main exiting\n"); Proc_Exit(0); }
PORT create_process (void (*ptr_to_new_proc) (PROCESS, PARAM), int prio, PARAM param, char *name) { //For interrupts volatile int saved_if; DISABLE_INTR(saved_if); //end for interrupts //Look for empty int i; for(i = 0; i < MAX_PROCS; i++){ if(pcb[i].used == FALSE) break; } MEM_ADDR esp; PROCESS new_proc = &pcb[i]; new_proc->magic = MAGIC_PCB; new_proc->used = TRUE; new_proc->state = STATE_READY; new_proc->priority = prio; new_proc->first_port = NULL; new_proc->name = name; PORT p = create_new_port(new_proc); esp = PROCESS_BASE - PROCESS_SIZE * i; poke_l(esp, param); esp -= sizeof(LONG); poke_l(esp, new_proc); esp -= sizeof(LONG); poke_l(esp, 0); esp -= sizeof(LONG); //For interrupts if(interrupts_initialized == TRUE) poke_l(esp, 512); else poke_l(esp, 0); esp -= sizeof(LONG); poke_l(esp, CODE_SELECTOR); esp -= sizeof(LONG); //End for interrupts poke_l(esp, ptr_to_new_proc); esp -= sizeof(LONG); //0 out register poke_l(esp, 0); //EAX esp -= sizeof(LONG); poke_l(esp, 0); //ECX esp -= sizeof(LONG); poke_l(esp, 0); //EDX esp -= sizeof(LONG); poke_l(esp, 0); //EBX esp -= sizeof(LONG); poke_l(esp, 0); //EBP esp -= sizeof(LONG); poke_l(esp, 0); //ESI esp -= sizeof(LONG); poke_l(esp, 0); //EDI //Save the Stack pointer new_proc->esp = esp; add_ready_queue(new_proc); //For interrupts ENABLE_INTR(saved_if); //End for interrupts return p; }
//HOMEWORK 3 PORT create_process (void (*ptr_to_new_proc) (PROCESS, PARAM), int prio, PARAM param, char *name) { //initialize the process values LONG default_value = 0; MEM_ADDR esp; PROCESS new_proc; PORT new_port; //HW7 volatile int flag;//disable interrupts DISABLE_INTR(flag); new_proc = next_proc_ptr; next_proc_ptr = new_proc->next; //HW7 ENABLE_INTR (flag);//reenable interrupts new_proc->magic = MAGIC_PCB; new_proc->used = TRUE; new_proc->state = STATE_READY; new_proc->priority = prio; new_proc->first_port = NULL; new_proc->name = name; new_port = create_new_port(new_proc); esp = 640 * 1024 - (new_proc - pcb) * 16 * 1024; //PARAM esp = pushStack(esp, (LONG)param); //PROCESS esp = pushStack(esp, (LONG)new_proc); //RETURN ADDRESS esp = pushStack(esp, default_value); //Push interrupt flags if initialized //HW7 - slide 20 EFLAGS if (interrupts_initialized) { esp = pushStack(esp, 512); } else { esp = pushStack(esp, default_value); } //Push CodeSelector esp = pushStack(esp, CODE_SELECTOR); //ADDRESS OF NEW PROCESS esp = pushStack(esp, (LONG)ptr_to_new_proc); //EAX esp = pushStack(esp, default_value); //ECX esp = pushStack(esp, default_value); //EDX esp = pushStack(esp, default_value); //EBX esp = pushStack(esp, default_value); //EBP esp = pushStack(esp, default_value); //ESI esp = pushStack(esp, default_value); //EDI esp = pushStack(esp, default_value); new_proc->esp = esp; add_ready_queue (new_proc); return new_port; }
void remove_cursor(WINDOW* wnd){ volatile int saved_if; DISABLE_INTR(saved_if); poke_w(0xb8000 + ((wnd->x + wnd->cursor_x)*2) + ((wnd->y + wnd->cursor_y)*160) , 0); ENABLE_INTR(saved_if); }
PORT create_process (void (*ptr_to_new_proc) (PROCESS, PARAM), int prio, PARAM param, char *name) { MEM_ADDR esp; PROCESS new_proc; PORT new_port; volatile int flag; DISABLE_INTR (flag); if (prio >= MAX_READY_QUEUES) panic ("create(): Bad priority"); if (next_free_pcb == NULL) panic ("create(): PCB full"); new_proc = next_free_pcb; next_free_pcb = new_proc->next; ENABLE_INTR (flag); new_proc->used = TRUE; new_proc->magic = MAGIC_PCB; new_proc->state = STATE_READY; new_proc->priority = prio; new_proc->first_port = NULL; new_proc->name = name; new_port = create_new_port (new_proc); /* Compute linear address of new process' system stack */ esp = 640 * 1024 - (new_proc - pcb) * 16 * 1024; #define PUSH(x) esp -= 4; \ poke_l (esp, (LONG) x); /* Initialize the stack for the new process */ PUSH (param); /* First data */ PUSH (new_proc); /* Self */ PUSH (0); /* Dummy return address */ if (interrupts_initialized) { PUSH (512); /* Flags with enabled Interrupts */ } else { PUSH (0); /* Flags with disabled Interrupts */ } PUSH (CODE_SELECTOR); /* Kernel code selector */ PUSH (ptr_to_new_proc); /* Entry point of new process */ PUSH (0); /* EAX */ PUSH (0); /* ECX */ PUSH (0); /* EDX */ PUSH (0); /* EBX */ PUSH (0); /* EBP */ PUSH (0); /* ESI */ PUSH (0); /* EDI */ #undef PUSH /* Save context ptr (actually current stack pointer) */ new_proc->esp = esp; add_ready_queue (new_proc); return new_port; }