Esempio n. 1
0
/*===========================================================================*
 *				dsp_dma_setup
 *===========================================================================*/
PRIVATE void dsp_dma_setup(phys_bytes address, int count)
{
	pvb_pair_t pvb[9];


	dprint("Setting up %d bit DMA\n", DspBits);

	if(DspBits == 8) {   /* 8 bit sound */
		count--;     

		pv_set(pvb[0], DMA8_MASK, SB_DMA_8 | 0x04);      /* Disable DMA channel */
		pv_set(pvb[1], DMA8_CLEAR, 0x00);		       /* Clear flip flop */

		/* set DMA mode */
		pv_set(pvb[2], DMA8_MODE, (DmaMode == DEV_WRITE_S ? DMA8_AUTO_PLAY : DMA8_AUTO_REC)); 

		pv_set(pvb[3], DMA8_ADDR, (address >>  0) & 0xff);        /* Low_byte of address */
		pv_set(pvb[4], DMA8_ADDR, (address >>  8) & 0xff);        /* High byte of address */
		pv_set(pvb[5], DMA8_PAGE, (address >> 16) & 0xff);        /* 64K page number */
		pv_set(pvb[6], DMA8_COUNT, (count >> 0) & 0xff);          /* Low byte of count */
		pv_set(pvb[7], DMA8_COUNT, (count >> 8) & 0xff);          /* High byte of count */
		pv_set(pvb[8], DMA8_MASK, SB_DMA_8);	       /* Enable DMA channel */

		sys_voutb(pvb, 9);
	} else {  /* 16 bit sound */
Esempio n. 2
0
/*===========================================================================*
 *				printer_intr				     *
 *===========================================================================*/
static void printer_intr(unsigned int UNUSED(mask))
{
/* This function does the actual output to the printer. This is called on an
 * interrupt message sent from the generic interrupt handler that 'forwards'
 * interrupts to this driver. The generic handler did not reenable the printer
 * IRQ yet! 
 */

  u32_t status;
  pvb_pair_t char_out[3];

  if (oleft == 0) {
	/* Nothing more to print.  Turn off printer interrupts in case they
	 * are level-sensitive as on the PS/2.  This should be safe even
	 * when the printer is busy with a previous character, because the
	 * interrupt status does not affect the printer.
	 */
	if(sys_outb(port_base + 2, PR_SELECT) != OK) {
		printf("printer: sys_outb of %x failed\n", port_base+2);
		panic("sys_outb failed");
	}
	if(sys_irqenable(&irq_hook_id) != OK) {
		panic("sys_irqenable failed");
	}
	return;
  }

  do {
	/* Loop to handle fast (buffered) printers.  It is important that
	 * processor interrupts are not disabled here, just printer interrupts.
	 */
	if(sys_inb(port_base + 1, &status) != OK) {
		printf("printer: sys_inb of %x failed\n", port_base+1);
		panic("sys_inb failed");
	}
	if ((status & STATUS_MASK) == BUSY_STATUS) {
		/* Still busy with last output.  This normally happens
		 * immediately after doing output to an unbuffered or slow
		 * printer.  It may happen after a call from prepare_output or
		 * pr_restart, since they are not synchronized with printer
		 * interrupts.  It may happen after a spurious interrupt.
		 */
		if(sys_irqenable(&irq_hook_id) != OK) {
			panic("sys_irqenable failed");
		}
		return;
	}
	if ((status & STATUS_MASK) == NORMAL_STATUS) {
		/* Everything is all right.  Output another character. */
		pv_set(char_out[0], port_base, *optr);	
		optr++;
		pv_set(char_out[1], port_base+2, ASSERT_STROBE);
		pv_set(char_out[2], port_base+2, NEGATE_STROBE);
		if(sys_voutb(char_out, 3) != OK) {
			/* request series of port outb */
			panic("sys_voutb failed");
		}

		user_vir_d++;
		user_left--;
	} else {
		/* Error.  This would be better ignored (treat as busy). */
		done_status = status;
		output_done();
		if(sys_irqenable(&irq_hook_id) != OK) {
			panic("sys_irqenable failed");
		}
		return;
	}
  }
  while (--oleft != 0);

  /* Finished printing chunk OK. */
  done_status = OK;
  output_done();
  if(sys_irqenable(&irq_hook_id) != OK) {
	panic("sys_irqenable failed");
  }
}