Beispiel #1
0
static int
gus_midi_out (int dev, unsigned char midi_byte)
{

  unsigned long   flags;

  /*
   * Drain the local queue first
   */

  DISABLE_INTR (flags);

  while (qlen && dump_to_midi (tmp_queue[qhead]))
    {
      qlen--;
      qhead++;
    }

  RESTORE_INTR (flags);

  /*
   * Output the byte if the local queue is empty.
   */

  if (!qlen)
    if (dump_to_midi (midi_byte))
      return 1;			/*
				 * OK
				 */

  /*
   * Put to the local queue
   */

  if (qlen >= 256)
    return 0;			/*
				 * Local queue full
				 */

  DISABLE_INTR (flags);

  tmp_queue[qtail] = midi_byte;
  qlen++;
  qtail++;

  RESTORE_INTR (flags);

  return 1;
}
Beispiel #2
0
void output_string(WINDOW* wnd, const char *str){
  volatile int saved_if;
  DISABLE_INTR(saved_if);
  short tempchar;
  int len, i = 0;
  len = k_strlen(str);

  while(i < len){
    tempchar = (0x0f << 8) | str[i];
    if(str[i] != '\n'){
      poke_w(0xb8000 + ((wnd->x + wnd->cursor_x)*2) + ((wnd->y + wnd->cursor_y)*160) , tempchar);
    }
    if(wnd->cursor_x+1 >= wnd->width || str[i] == '\n'){
      if(wnd->cursor_y +1 >= wnd->height){
        scroll(wnd);
      }
      else{wnd->cursor_y++;}
      wnd->cursor_x =0;
    }
    else{
      wnd->cursor_x++;
    }
    i++;
  }
  ENABLE_INTR(saved_if);
}
Beispiel #3
0
Datei: ipc.c Projekt: tojonol/tos
PORT create_new_port (PROCESS owner)
{
    //get next port and advance port reference
    PORT newport = next_port;
    volatile int flag;
    DISABLE_INTR (flag);
    next_port = next_port->next;

    //Port Data Structure
    newport->magic = MAGIC_PORT;
    newport->used = TRUE;
    newport->open = TRUE;
    newport->owner =  owner;
    newport->blocked_list_head = NULL;
    newport->blocked_list_tail = NULL;
    if(owner->first_port != NULL)
    {
        newport->next = owner->first_port;
    }
    else
    {
        newport->next = NULL;
    }
    owner->first_port = newport;
    ENABLE_INTR (flag);
    return newport;
}
Beispiel #4
0
void show_cursor(WINDOW* wnd){
  volatile int saved_if;
  DISABLE_INTR(saved_if);
  short cursor = (0x82 << 8) | wnd->cursor_char;
  poke_w(0xb8000 + ((wnd->x + wnd->cursor_x)*2) + ((wnd->y + wnd->cursor_y)*160) , cursor);
  ENABLE_INTR(saved_if);
}
Beispiel #5
0
static int
dump_to_midi (unsigned char midi_byte)
{
  unsigned long   flags;
  int             ok = 0;

  output_used = 1;

  DISABLE_INTR (flags);

  if (GUS_MIDI_STATUS () & MIDI_XMIT_EMPTY)
    {
      ok = 1;
      OUTB (midi_byte, u_MidiData);
    }
  else
    {
      /*
       * Enable Midi xmit interrupts (again)
       */
      gus_midi_control |= MIDI_ENABLE_XMIT;
      OUTB (gus_midi_control, u_MidiControl);
    }

  RESTORE_INTR (flags);
  return ok;
}
Beispiel #6
0
Datei: ipc.c Projekt: tojonol/tos
//Sends data to specified port
void send (PORT dest_port, void* data)
{
    volatile int flag;
    DISABLE_INTR(flag);
    PROCESS dest_process = dest_port->owner;
    //if (reciever is recieved blocked and port is open)
    if (dest_port->open && dest_process->state == STATE_RECEIVE_BLOCKED)
    {
        dest_process->param_proc = active_proc;
        dest_process->param_data = data;
        //Change Reciever to STATE_READY
        //taken care of by dispatch
        add_ready_queue (dest_process);
        //Change to STATE_REPLY_BLOCKED
        active_proc->state   = STATE_REPLY_BLOCKED;
    }
    //else
    else
    {
        active_proc->param_data = data;
        //Get on the send blocked list of the port
        if (dest_port->blocked_list_head == NULL)
            dest_port->blocked_list_head = active_proc;
        else
            dest_port->blocked_list_tail->next_blocked = active_proc;
        dest_port->blocked_list_tail = active_proc;
        active_proc->next_blocked = NULL;
        //change state to STATE_SEND_BLOCKED
        active_proc->state = STATE_SEND_BLOCKED;
    }
    active_proc->param_data = data;
    remove_ready_queue (active_proc);
    resign();
    ENABLE_INTR(flag);
}
Beispiel #7
0
static int
sb16midi_out (int dev, unsigned char midi_byte)
{
  int             timeout;
  unsigned long   flags;

  /*
   * Test for input since pending input seems to block the output.
   */

  DISABLE_INTR (flags);

  if (input_avail ())
    sb16midi_input_loop ();

  RESTORE_INTR (flags);

  /*
   * Sometimes it takes about 13000 loops before the output becomes ready
   * (After reset). Normally it takes just about 10 loops.
   */

  for (timeout = 30000; timeout > 0 && !output_ready (); timeout--);	/*
									 * Wait
									 */

  if (!output_ready ())
    {
      printk ("MPU-401: Timeout\n");
      return 0;
    }

  sb16midi_write (midi_byte);
  return 1;
}
Beispiel #8
0
Datei: ipc.c Projekt: tojonol/tos
//Sends data to specified port
void message (PORT dest_port, void* data)
{
    volatile int flag;
    DISABLE_INTR(flag);
    PROCESS dest_process = dest_port->owner;
    //if (receiver is receive blocked and port is open)
    if (dest_process->state == STATE_RECEIVE_BLOCKED && dest_port->open)
    {
        dest_process->param_proc  = active_proc;
        dest_process->param_data = data;
        //Change receiver to STATE_READY
        add_ready_queue (dest_process);
    }
    //else
    else
    {
        active_proc->param_data = data;
        //Get on the send blocked list of the port
        if (dest_port->blocked_list_head == NULL)
            dest_port->blocked_list_head = active_proc;
        else
            dest_port->blocked_list_tail->next_blocked = active_proc;
        dest_port->blocked_list_tail = active_proc;
        active_proc->next_blocked = NULL;
        remove_ready_queue (active_proc);
        //Change to STATE_MESSAGE_BLOCKED
        active_proc->state = STATE_MESSAGE_BLOCKED;
        active_proc->param_data = data;
    }
    resign();
    ENABLE_INTR(flag);
}
Beispiel #9
0
Datei: ipc.c Projekt: tojonol/tos
void reply (PROCESS sender)
{
    volatile int flag;
    DISABLE_INTR (flag);
    //Add the process replied to back to the ready queue
    add_ready_queue (sender);
    //resign()
    resign();
    ENABLE_INTR (flag);
}
Beispiel #10
0
void move_cursor(WINDOW* wnd, int x, int y){
  volatile int saved_if;
  DISABLE_INTR(saved_if);
  if((0 <=  x )&& (x < wnd->width)){
    wnd->cursor_x = x;
  }
  if((0 <=  y) && (y < wnd->height)){
    wnd->cursor_y = y;
  }
  ENABLE_INTR(saved_if);
}
Beispiel #11
0
Datei: ipc.c Projekt: tojonol/tos
void* receive (PROCESS* sender)
{
    volatile int flag;
    DISABLE_INTR(flag);
    PROCESS receiver_process;
    //Scanning send blocked list
    PORT p = active_proc->first_port;
    while (p != NULL) {
        if (p->open && p->blocked_list_head != NULL)
            // Found a process on the send blocked list
            break;
        p = p->next;
    }
    //if (send blocked list is not empty)
    if (p != NULL)
    {

        //sender = first process on the send blocked list
        receiver_process = p->blocked_list_head;
        *sender = receiver_process;

        //data = receiver_process->param_data;
        //cleanup pointer to next process
        p->blocked_list_head = p->blocked_list_head->next_blocked;
        if (p->blocked_list_head == NULL)
            p->blocked_list_tail = NULL;

        //if (sender is STATE_MESSAGE_BLOCKED)
        if (receiver_process->state == STATE_MESSAGE_BLOCKED)
        {
            //Change state of sender to STATE_READY
            add_ready_queue (receiver_process);
            ENABLE_INTR (flag);
            return receiver_process->param_data;
        }
        //if (sender is STATE_SEND_BLOCKED)
        else if (receiver_process->state == STATE_SEND_BLOCKED)
        {
            //Change state of sender to STATE_REPLY_BLOCKED
            receiver_process->state = STATE_REPLY_BLOCKED;
	          ENABLE_INTR (flag);
            return receiver_process->param_data;
        }
    }
    //else
    remove_ready_queue (active_proc);
    active_proc->param_data = NULL;
    active_proc->state = STATE_RECEIVE_BLOCKED;
    //Change to STATE_RECEIVED_BLOCKED
    resign();
    *sender = active_proc->param_proc;
    ENABLE_INTR (flag);
    return active_proc->param_data;
}
/*
 * This sets aspects of the Mixer that are not volume levels. (Recording
 * source, filter level, I/O filtering, and stereo.)
 */
static int
mixer_set_params (struct sb_mixer_params *user_p)
{
  struct sb_mixer_params p;
  S_BYTE          val;
  int             src;
  unsigned long   flags;

  IOCTL_FROM_USER ((char *) &p, (char *) user_p, 0, sizeof (p));

  if (p.record_source != SRC_MIC
      && p.record_source != SRC_CD
      && p.record_source != SRC_LINE)
    return (RET_ERROR (EINVAL));

  /*
   * I'm not sure if this is The Right Thing.  Should stereo be entirely
   * under control of DSP?  I like being able to toggle it while a sound is
   * playing, so I do this... because I can.
   */

  DISABLE_INTR (flags);

  val = (pas_read (PCM_CONTROL) & ~P_C_MIXER_CROSS_FIELD) | P_C_MIXER_CROSS_R_TO_R | P_C_MIXER_CROSS_L_TO_L;
  if (!p.dsp_stereo)
    val |= (P_C_MIXER_CROSS_R_TO_L | P_C_MIXER_CROSS_L_TO_R);	/* Mono */
  pas_write (val, PCM_CONTROL);

  RESTORE_INTR (flags);

  switch (p.record_source)
    {
    case SRC_CD:
      src = SOUND_MASK_CD;
      break;

    case SRC_LINE:
      src = SOUND_MASK_LINE;
      break;

    default:
      src = SOUND_MASK_MIC;
      break;
    }

  pas_mixer_set (SOUND_MIXER_RECSRC, src);

  /*
   * setmixer (OUT_FILTER, ((dsp_stereo ? STEREO_DAC : MONO_DAC) |
   * (p.filter_output ? FILT_ON : FILT_OFF)));
   */
  return (0);
}
Beispiel #13
0
void clear_window(WINDOW* wnd){
  volatile int saved_if;
  DISABLE_INTR(saved_if);
  int w, h;
  for(h=0; h < wnd->height; h++){
    for(w=0; w < wnd->width; w++){
      poke_w(0xb8000 + ((wnd->x + w)*2) + ((wnd->y + h)*160) ,0);
    }
  }
  wnd->cursor_x = 0;
  wnd->cursor_y = 0;
  ENABLE_INTR(saved_if);
}
Beispiel #14
0
static void
tmr_reset (void)
{
  unsigned long   flags;

  DISABLE_INTR (flags);
  tmr_offs = 0;
  ticks_offs = 0;
  tmr_ctr = 0;
  next_event_time = 0xffffffff;
  prev_event_time = 0;
  curr_ticks = 0;
  RESTORE_INTR (flags);
}
Beispiel #15
0
void
sb_midi_interrupt (int dummy)
{
  unsigned long   flags;
  unsigned char   data;

  DISABLE_INTR (flags);

  data = INB (DSP_READ);
  if (input_opened)
    midi_input_intr (my_dev, data);

  RESTORE_INTR (flags);
}
Beispiel #16
0
static int
reset_sb16midi (void)
{
  unsigned long   flags;
  int             ok, timeout, n;

  /*
   * Send the RESET command. Try again if no success at the first time.
   */

  ok = 0;

  DISABLE_INTR (flags);

  for (n = 0; n < 2 && !ok; n++)
    {
      for (timeout = 30000; timeout < 0 && !output_ready (); timeout--);	/*
										 * Wait
										 */
      sb16midi_cmd (MPU_RESET);	/*
				 * Send MPU-401 RESET Command
				 */

      /*
       * Wait at least 25 msec. This method is not accurate so let's make the
       * loop bit longer. Cannot sleep since this is called during boot.
       */

      for (timeout = 50000; timeout > 0 && !ok; timeout--)
	if (input_avail ())
	  if (sb16midi_read () == MPU_ACK)
	    ok = 1;

    }

  sb16midi_opened = 0;
  if (ok)
    sb16midi_input_loop ();	/*
				 * Flush input before enabling interrupts
				 */

  RESTORE_INTR (flags);

  return ok;
}
Beispiel #17
0
void
gus_midi_interrupt (int dummy)
{
  unsigned char   stat, data;
  unsigned long   flags;

  DISABLE_INTR (flags);

  stat = GUS_MIDI_STATUS ();

  if (stat & MIDI_RCV_FULL)
    {
      data = INB (u_MidiData);
      if (input_opened)
	midi_input_intr (my_dev, data);
    }

  if (stat & MIDI_XMIT_EMPTY)
    {
      while (qlen && dump_to_midi (tmp_queue[qhead]))
	{
	  qlen--;
	  qhead++;
	}

      if (!qlen)
	{
	  /*
	   * Disable Midi output interrupts, since no data in the buffer
	   */
	  gus_midi_control &= ~MIDI_ENABLE_XMIT;
	  OUTB (gus_midi_control, u_MidiControl);
	}
    }

#if 0
  if (stat & MIDI_FRAME_ERR)
    printk ("GUS: Midi framing error\n");
  if (stat & MIDI_OVERRUN && input_opened)
    printk ("GUS: Midi input overrun\n");
#endif

  RESTORE_INTR (flags);
}
Beispiel #18
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 #19
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;
        case 14:
            poke_screen(wnd->x + wnd->width,
                    wnd->y + wnd->cursor_y,
                    (short unsigned int) 0xB3 | (default_color << 8));
            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 #20
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 #21
0
static int
gus_midi_buffer_status (int dev)
{
  unsigned long   flags;

  if (!output_used)
    return 0;

  DISABLE_INTR (flags);

  if (qlen && dump_to_midi (tmp_queue[qhead]))
    {
      qlen--;
      qhead++;
    }

  RESTORE_INTR (flags);

  return (qlen > 0) | !(GUS_MIDI_STATUS () & MIDI_XMIT_EMPTY);
}
Beispiel #22
0
long
attach_sb16midi (long mem_start, struct address_info *hw_config)
{
  int             ok, timeout;
  unsigned long   flags;

  sb16midi_base = hw_config->io_base;

  if (!sb16midi_detected)
    return RET_ERROR (EIO);

  DISABLE_INTR (flags);
  for (timeout = 30000; timeout < 0 && !output_ready (); timeout--);	/*
									 * Wait
									 */
  sb16midi_cmd (UART_MODE_ON);

  ok = 0;
  for (timeout = 50000; timeout > 0 && !ok; timeout--)
    if (input_avail ())
      if (sb16midi_read () == MPU_ACK)
	ok = 1;

  RESTORE_INTR (flags);

  if (num_midis >= MAX_MIDI_DEV)
    {
      printk ("Sound: Too many midi devices detected\n");
      return mem_start;
    }

#if defined(__FreeBSD__)
  printk ("sbmidi0: <SoundBlaster MPU-401>");
#else
  printk (" <SoundBlaster MPU-401>");
#endif

  std_midi_synth.midi_dev = my_dev = num_midis;
  midi_devs[num_midis++] = &sb16midi_operations;
  return mem_start;
}
Beispiel #23
0
static int
sb_midi_out (int dev, unsigned char midi_byte)
{
  unsigned long   flags;

  if (sb_midi_mode == NORMAL_MIDI)
    {
      DISABLE_INTR (flags);
      if (sb_dsp_command (0x38))
	sb_dsp_command (midi_byte);
      else
	printk ("SB Error: Unable to send a MIDI byte\n");
      RESTORE_INTR (flags);
    }
  else
    sb_dsp_command (midi_byte);	/*
				 * UART write
				 */

  return 1;
}
Beispiel #24
0
long
attach_uart6850 (long mem_start, struct address_info *hw_config)
{
  int             ok, timeout;
  unsigned long   flags;

  if (num_midis >= MAX_MIDI_DEV)
    {
      printk ("Sound: Too many midi devices detected\n");
      return mem_start;
    }

  uart6850_base = hw_config->io_base;
  uart6850_irq = hw_config->irq;

  if (!uart6850_detected)
    return RET_ERROR (EIO);

  DISABLE_INTR (flags);

  for (timeout = 30000; timeout < 0 && !output_ready (); timeout--);	/*
									 * Wait
									 */
  uart6850_cmd (UART_MODE_ON);

  ok = 1;

  RESTORE_INTR (flags);

#if defined(__FreeBSD__)
  printk ("uart0: <6850 Midi Interface>");
#else
  printk (" <6850 Midi Interface>");
#endif

  std_midi_synth.midi_dev = my_dev = num_midis;
  midi_devs[num_midis++] = &uart6850_operations;
  return mem_start;
}
Beispiel #25
0
PORT create_process (void (*ptr_to_new_proc) (PROCESS, PARAM), int prio, PARAM param, char *name) {
    volatile int lock;
    DISABLE_INTR(lock);
    int i;
    for(i = 1; i < MAX_PROCS; i++) {
        if(pcb[i].used == FALSE) {
            pcb[i].magic = MAGIC_PCB;
            pcb[i].used = TRUE;
            pcb[i].priority = (unsigned short) prio;
            pcb[i].state = STATE_READY;
            pcb[i].esp = get_new_stack_frame(i, ptr_to_new_proc, param);
            pcb[i].first_port = create_new_port(&pcb[i]);
            pcb[i].name = name;

            add_ready_queue(&pcb[i]);
            ENABLE_INTR(lock);
            return pcb[i].first_port;
        }
    }
    ENABLE_INTR(lock);
    return (PORT) NULL;
}
Beispiel #26
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 #27
0
static void
poll_uart6850 (unsigned long dummy)
{
  unsigned long   flags;

  DEFINE_TIMER (uart6850_timer, poll_uart6850);

  if (!(uart6850_opened & OPEN_READ))
    return;			/*
				 * No longer required
				 */

  DISABLE_INTR (flags);

  if (input_avail ())
    uart6850_input_loop ();

  ACTIVATE_TIMER (uart6850_timer, poll_uart6850, 1);	/*
							 * Come back later
							 */

  RESTORE_INTR (flags);
}
Beispiel #28
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 #29
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 #30
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;
}