⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dma.c

📁 一个微型操作系统源码
💻 C
字号:
/* * OSV * Copyright (C) 2002 Ciprian DOSOFTEI <rocksoul@mail.com> * All rights reserved. *  * http://backster.free.fr/osv * * This file is part of the OSV project. OSV is free software, also known as * "open source"; you can redistribute it and/or modify it under the terms  * of the GNU General Public License (GPL), version 2, as published by the Free * Software Foundation (FSF). To explore alternate licensing terms, contact  * the author at rocksoul@mail.com or +40740649907. *  * OSV is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE.  See the GPL for more details.  You should have * received a copy of the GPL along with OSV; see the file COPYING.  If * not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA. */#include <dma.h>#include <types.h>#include <asm/system.h>#include <asm/io.h>static byte dma_mask  [8] = { 0x0A, 0x0A, 0x0A, 0x0A, 0xD4, 0xD4, 0xD4, 0xD4 };static byte dma_mode  [8] = { 0x0B, 0x0B, 0x0B, 0x0B, 0xD6, 0xD6, 0xD6, 0xD6 };static byte dma_clear [8] = { 0x0C, 0x0C, 0x0C, 0x0C, 0xD8, 0xD8, 0xD8, 0xD8 };static byte dma_page  [8] = { 0x87, 0x83, 0x81, 0x82, 0x8F, 0x8B, 0x89, 0x8A };static byte dma_addr  [8] = { 0x00, 0x02, 0x04, 0x06, 0xC0, 0xC4, 0xC8, 0xCC };static byte dma_count [8] = { 0x01, 0x03, 0x05, 0x07, 0xC2, 0xC6, 0xCA, 0xCE };void setup_dma (dword channel, dword data_ptr, word length, 		transfer_type trans, mode_type mode,		BOOL auto_init, BOOL address_inc) {  dword offset, page;  MODE_REG mode_reg;  /* extract offset and page from the given data pointer */  offset = LOW_WORD(data_ptr);  page = HI_WORD(data_ptr);  /* prepare mode register fields */  mode_reg.fields.channel = channel % 4;  mode_reg.fields.transfer_type = trans;  mode_reg.fields.auto_init = auto_init;  mode_reg.fields.address_inc = address_inc;  mode_reg.fields.mode = mode;  /* Don't let anyone else mess up what we're doing. */  __cli ();  /* Set up the DMA channel so we can use it.  This tells the DMA */  /* that we're going to be using this channel.  (It's masked) */  pause_dma (channel);  /* Clear any data transfers that are currently executing. */  outb (dma_clear [channel], 0x00);  /* Send the specified mode to the DMA. */  outb (dma_mode [channel], mode_reg.value);  /* Send the offset address.  The first byte is the low base offset, the */  /* second byte is the high offset. */  outb (dma_addr [channel], LOW_BYTE(offset));  outb (dma_addr [channel], HI_BYTE(offset));  /* Send the physical page that the data lies on. */  outb (dma_page [channel], page);  /* Send the length of the data.  Again, low byte first. */  outb (dma_count [channel], LOW_BYTE((length - 1)));  outb (dma_count [channel], HI_BYTE((length - 1)));  /* Ok, we're done.  Enable the DMA channel (clear the mask). */  unpause_dma (channel);  /* Re-enable interrupts before we leave. */  __sti ();}void pause_dma (byte channel) {  /* All we have to do is mask the DMA channel's bit on. */  MASK_REG mask;  mask.fields.channel = channel % 4;  mask.fields.mask = 1;  outb (dma_mask [channel], mask.value);}void unpause_dma (byte channel) {  /* Simply clear the mask, and the DMA continues where it left off. */  MASK_REG mask;  mask.fields.channel = channel % 4;  mask.fields.mask = 0;  outb (dma_mask [channel], mask.value);}void stop_dma (byte channel) {  /* We need to set the mask bit for this channel, and then clear the */  /* selected channel.  Then we can clear the mask. */  pause_dma (channel);  /* Send the clear command. */  outb (dma_clear [channel], 0x00);  /* And clear the mask. */  unpause_dma (channel);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -