Beispiel #1
0
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);
}
Beispiel #2
0
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);
}
Beispiel #3
0
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);
}
Beispiel #4
0
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);
}
Beispiel #5
0
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);
}
Beispiel #6
0
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);
}
Beispiel #7
0
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);
}
Beispiel #8
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;
}
Beispiel #9
0
//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;
}
Beispiel #10
0
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);
}
Beispiel #11
0
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;
}