tmp floopy driver save, no test
This commit is contained in:
parent
08d13e033c
commit
eb5ea946a6
|
@ -0,0 +1,187 @@
|
|||
#ifndef _DMA_H
|
||||
#define _DMA_H
|
||||
|
||||
|
||||
#define MAX_DMA_CHANNELS 8
|
||||
|
||||
/* 8237 DMA controllers */
|
||||
#define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */
|
||||
#define IO_DMA2_BASE 0xC0 /* 16 bit master DMA, ch 4(=slave input)..7 */
|
||||
|
||||
/* DMA controller registers */
|
||||
#define DMA1_CMD_REG 0x08 /* command register (w) */
|
||||
#define DMA1_STAT_REG 0x08 /* status register (r) */
|
||||
#define DMA1_REQ_REG 0x09 /* request register (w) */
|
||||
#define DMA1_MASK_REG 0x0A /* single-channel mask (w) */
|
||||
#define DMA1_MODE_REG 0x0B /* mode register (w) */
|
||||
#define DMA1_CLEAR_FF_REG 0x0C /* clear pointer flip-flop (w) */
|
||||
#define DMA1_TEMP_REG 0x0D /* Temporary Register (r) */
|
||||
#define DMA1_RESET_REG 0x0D /* Master Clear (w) */
|
||||
#define DMA1_CLR_MASK_REG 0x0E /* Clear Mask */
|
||||
#define DMA1_MASK_ALL_REG 0x0F /* all-channels mask (w) */
|
||||
|
||||
#define DMA2_CMD_REG 0xD0 /* command register (w) */
|
||||
#define DMA2_STAT_REG 0xD0 /* status register (r) */
|
||||
#define DMA2_REQ_REG 0xD2 /* request register (w) */
|
||||
#define DMA2_MASK_REG 0xD4 /* single-channel mask (w) */
|
||||
#define DMA2_MODE_REG 0xD6 /* mode register (w) */
|
||||
#define DMA2_CLEAR_FF_REG 0xD8 /* clear pointer flip-flop (w) */
|
||||
#define DMA2_TEMP_REG 0xDA /* Temporary Register (r) */
|
||||
#define DMA2_RESET_REG 0xDA /* Master Clear (w) */
|
||||
#define DMA2_CLR_MASK_REG 0xDC /* Clear Mask */
|
||||
#define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */
|
||||
|
||||
#define DMA_ADDR_0 0x00 /* DMA address registers */
|
||||
#define DMA_ADDR_1 0x02
|
||||
#define DMA_ADDR_2 0x04
|
||||
#define DMA_ADDR_3 0x06
|
||||
#define DMA_ADDR_4 0xC0
|
||||
#define DMA_ADDR_5 0xC4
|
||||
#define DMA_ADDR_6 0xC8
|
||||
#define DMA_ADDR_7 0xCC
|
||||
|
||||
#define DMA_CNT_0 0x01 /* DMA count registers */
|
||||
#define DMA_CNT_1 0x03
|
||||
#define DMA_CNT_2 0x05
|
||||
#define DMA_CNT_3 0x07
|
||||
#define DMA_CNT_4 0xC2
|
||||
#define DMA_CNT_5 0xC6
|
||||
#define DMA_CNT_6 0xCA
|
||||
#define DMA_CNT_7 0xCE
|
||||
|
||||
#define DMA_PAGE_0 0x87 /* DMA page registers */
|
||||
#define DMA_PAGE_1 0x83
|
||||
#define DMA_PAGE_2 0x81
|
||||
#define DMA_PAGE_3 0x82
|
||||
#define DMA_PAGE_5 0x8B
|
||||
#define DMA_PAGE_6 0x89
|
||||
#define DMA_PAGE_7 0x8A
|
||||
|
||||
#define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */
|
||||
#define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */
|
||||
#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */
|
||||
|
||||
/*
|
||||
* 启用指定的DMA通道
|
||||
*/
|
||||
static __inline__ void EnableDma(unsigned int dmanr)
|
||||
{
|
||||
if (dmanr<=3)
|
||||
outb(dmanr, DMA1_MASK_REG);
|
||||
else
|
||||
outb(dmanr & 3, DMA2_MASK_REG);
|
||||
}
|
||||
|
||||
/*
|
||||
* 禁用指定的DMA通道
|
||||
*/
|
||||
static __inline__ void DisableDma(unsigned int dmanr)
|
||||
{
|
||||
if (dmanr<=3)
|
||||
outb(dmanr | 4, DMA1_MASK_REG);
|
||||
else
|
||||
outb((dmanr & 3) | 4, DMA2_MASK_REG);
|
||||
}
|
||||
|
||||
/*
|
||||
* 清空DMA 晶体计数器
|
||||
*/
|
||||
static __inline__ void ClearDmaFF(unsigned int dmanr)
|
||||
{
|
||||
if (dmanr<=3)
|
||||
outb(0, DMA1_CLEAR_FF_REG);
|
||||
else
|
||||
outb(0, DMA2_CLEAR_FF_REG);
|
||||
}
|
||||
|
||||
/*
|
||||
* 清空DMA 晶体计数器
|
||||
*/
|
||||
static __inline__ void SetDmaMode(unsigned int dmanr, char mode)
|
||||
{
|
||||
if (dmanr<=3)
|
||||
outb(mode | dmanr, DMA1_MODE_REG);
|
||||
else
|
||||
outb(mode | (dmanr&3), DMA2_MODE_REG);
|
||||
}
|
||||
|
||||
/*
|
||||
* 设定DMA 页面寄存器
|
||||
*/
|
||||
static __inline__ void SetDmaPage(unsigned int dmanr, char pagenr)
|
||||
{
|
||||
switch(dmanr) {
|
||||
case 0:
|
||||
outb(pagenr, DMA_PAGE_0);
|
||||
break;
|
||||
case 1:
|
||||
outb(pagenr, DMA_PAGE_1);
|
||||
break;
|
||||
case 2:
|
||||
outb(pagenr, DMA_PAGE_2);
|
||||
break;
|
||||
case 3:
|
||||
outb(pagenr, DMA_PAGE_3);
|
||||
break;
|
||||
case 5:
|
||||
outb(pagenr & 0xfe, DMA_PAGE_5);
|
||||
break;
|
||||
case 6:
|
||||
outb(pagenr & 0xfe, DMA_PAGE_6);
|
||||
break;
|
||||
case 7:
|
||||
outb(pagenr & 0xfe, DMA_PAGE_7);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 设定DMA 传输高速缓冲区地址
|
||||
*/
|
||||
static __inline__ void SetDmaAddr(unsigned int dmanr, unsigned int a)
|
||||
{
|
||||
SetDmaPage(dmanr, a>>16);
|
||||
if (dmanr <= 3) {
|
||||
outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
|
||||
outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
|
||||
} else {
|
||||
outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
|
||||
outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 设定DMA 传输块数
|
||||
*/
|
||||
static __inline__ void SetDmaCount(unsigned int dmanr, unsigned int count)
|
||||
{
|
||||
count--;
|
||||
if (dmanr <= 3) {
|
||||
outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
|
||||
outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
|
||||
} else {
|
||||
outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
|
||||
outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 获得DMA 传输剩余块数
|
||||
*/
|
||||
static __inline__ int GetDmaResidue(unsigned int dmanr)
|
||||
{
|
||||
unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE
|
||||
: ((dmanr&3)<<2) + 2 + IO_DMA2_BASE;
|
||||
|
||||
/* using short to get 16-bit wrap around */
|
||||
unsigned short count;
|
||||
count = 1 + inb(io_port);
|
||||
count += inb(io_port) << 8;
|
||||
return (dmanr<=3)? count : (count<<1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,234 @@
|
|||
|
||||
#include <rtthread.h>
|
||||
#include <rthw.h>
|
||||
|
||||
#include <bsp.h>
|
||||
|
||||
typedef rt_uint8_t u8;
|
||||
typedef rt_uint16_t u16;
|
||||
typedef rt_uint32_t u32;
|
||||
|
||||
typedef rt_int8_t s8;
|
||||
typedef rt_int16_t s16;
|
||||
typedef rt_int32_t s32;
|
||||
|
||||
#include "floppy.h"
|
||||
#include "dma.h"
|
||||
|
||||
#define panic(str) rt_kprintf("panic::" str)
|
||||
|
||||
#define _local_irq_save(level) level = rt_hw_interrupt_disable()
|
||||
#define _local_irq_restore(level) rt_hw_interrupt_enable(level)
|
||||
|
||||
static u8 floppy_buffer[512]; /* 软盘高速缓冲区地址指针 */
|
||||
|
||||
#define MAX_REPLIES 7
|
||||
static u8 floppy_reply_buffer[MAX_REPLIES]; /* 软驱回应缓冲区 */
|
||||
#define ST0 (floppy_reply_buffer[0]) /* 软驱回应0号字节 */
|
||||
#define ST1 (floppy_reply_buffer[1]) /* 软驱回应1号字节 */
|
||||
#define ST2 (floppy_reply_buffer[2]) /* 软驱回应2号字节 */
|
||||
#define ST3 (floppy_reply_buffer[3]) /* 软驱回应3号字节 */
|
||||
|
||||
|
||||
static char *floppy_inc_name; /* 软驱型号名 */
|
||||
static char *floppy_type;
|
||||
static u32 floppy_motor=0; /* 软驱马达状态字节 */
|
||||
|
||||
/**********************功能函数***************************/
|
||||
static void floppy_result(void); /* 获得软驱响应状态 */
|
||||
static u32 floppy_sendbyte(u32); /* 向软驱控制寄存器发送一个控制字节 */
|
||||
static u32 floppy_getbyte(void); /* 从软驱数据寄存器得到一个数据字节 */
|
||||
static u32 floppy_get_info(void); /* 得到软驱信息 */
|
||||
static void floppy_motorOn(void); /* 打开软驱马达 */
|
||||
static void floppy_motorOff(void); /* 关闭软驱马达 */
|
||||
static void floppy_setmode(void); /* 软驱模式设置 */
|
||||
static void block_to_hts(u32, u32*, u32*, u32*); /* 逻辑块转为磁盘头、磁道号和扇区号 */
|
||||
static void floppy_setupDMA(void); /* 设置软驱DMA通道 */
|
||||
static void floppy_read_cmd(u32 blk); /* 从软盘上读取指定的逻辑块到缓冲区 */
|
||||
|
||||
|
||||
void floppy_result(void)
|
||||
{
|
||||
u8 stat, i,count;
|
||||
i=0;
|
||||
for(count=0; count<0xFF; count++)
|
||||
{
|
||||
stat = inb( FD_STATUS ) & (STATUS_READY|STATUS_DIR|STATUS_BUSY); //读取状态寄存器
|
||||
if (stat == STATUS_READY)
|
||||
return;
|
||||
if (stat == (STATUS_READY|STATUS_DIR|STATUS_BUSY))
|
||||
{
|
||||
if(i>7) break;
|
||||
floppy_reply_buffer[i++]=inb_p(FD_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
panic("Get floppy status times out !\n");
|
||||
}
|
||||
|
||||
u32 floppy_sendbyte( u32 value )
|
||||
{
|
||||
u8 stat, i;
|
||||
|
||||
for ( i = 0; i < 128; i++ ) {
|
||||
stat = inb( FD_STATUS ) & (STATUS_READY|STATUS_DIR); //读取状态寄存器
|
||||
if ( stat == STATUS_READY )
|
||||
{
|
||||
outb( value ,FD_DATA); //将参数写入数据寄存器
|
||||
return 1;
|
||||
}
|
||||
io_delay(); // 作一些延迟
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
u32 floppy_getbyte(void)
|
||||
{
|
||||
u8 stat, i;
|
||||
|
||||
for ( i = 0; i < 128; i++ ) {
|
||||
stat = inb( FD_STATUS ) & (STATUS_READY|STATUS_DIR|STATUS_BUSY); //读取状态寄存器
|
||||
if (stat == STATUS_READY)
|
||||
return -1;
|
||||
if ( stat == 0xD0 )
|
||||
return inb(FD_DATA);
|
||||
io_delay();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
u32 floppy_get_info(void)
|
||||
{
|
||||
u32 i;
|
||||
u8 CmType, FdType;
|
||||
|
||||
floppy_sendbyte(0x10);
|
||||
i = floppy_getbyte();
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0x80: floppy_inc_name = "NEC765A controller"; break;
|
||||
case 0x90: floppy_inc_name = "NEC765B controller"; break;
|
||||
default: floppy_inc_name = "Enhanced controller"; break;
|
||||
}
|
||||
|
||||
CmType = readcmos(0x10); //read floppy type from cmos
|
||||
FdType = (CmType>>4) & 0x07;
|
||||
|
||||
if ( FdType == 0 )
|
||||
panic("Floppy driver not found!");
|
||||
|
||||
switch( FdType )
|
||||
{
|
||||
case 0x02: // 1.2MB
|
||||
floppy_type = "1.2MB";
|
||||
break;
|
||||
|
||||
case 0x04: // 1.44MB 标准软盘
|
||||
floppy_type = "1.44MB";
|
||||
break;
|
||||
|
||||
case 0x05: // 2.88MB
|
||||
floppy_type = "2.88MB";
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void floppy_motorOn( void )
|
||||
{
|
||||
u32 eflags;
|
||||
if (!floppy_motor)
|
||||
{
|
||||
_local_irq_save(eflags);
|
||||
outb(28,FD_DOR);
|
||||
floppy_motor = 1;
|
||||
_local_irq_restore(eflags);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void floppy_motorOff( void )
|
||||
{
|
||||
u32 eflags;
|
||||
if (floppy_motor)
|
||||
{
|
||||
_local_irq_save(eflags);
|
||||
outb(12,FD_DOR);
|
||||
floppy_motor = 0;
|
||||
_local_irq_restore(eflags);
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void floppy_setmode(void)
|
||||
{
|
||||
floppy_sendbyte (FD_SPECIFY);
|
||||
floppy_sendbyte (0xcf);
|
||||
floppy_sendbyte (0x06);
|
||||
outb (0,FD_DCR);
|
||||
}
|
||||
|
||||
|
||||
void block_to_hts(u32 block, u32 *head, u32 *track, u32 *sector )
|
||||
{
|
||||
*head = ( block % ( 18 * 2 ) ) /18;
|
||||
*track = block / ( 18 * 2 );
|
||||
*sector = block % 18 + 1;
|
||||
}
|
||||
|
||||
|
||||
void floppy_setupDMA(void)
|
||||
{
|
||||
u32 eflags;
|
||||
_local_irq_save(eflags);
|
||||
DisableDma(2);
|
||||
ClearDmaFF(2);
|
||||
SetDmaMode(2,DMA_MODE_READ);
|
||||
SetDmaAddr(2,(unsigned long)floppy_buffer);
|
||||
SetDmaCount(2,512);
|
||||
EnableDma(2);
|
||||
_local_irq_restore(eflags);
|
||||
}
|
||||
|
||||
|
||||
void floppy_read_cmd(u32 blk)
|
||||
{
|
||||
u32 head;
|
||||
u32 track;
|
||||
u32 sector;
|
||||
|
||||
block_to_hts(blk,&head,&track,§or);
|
||||
|
||||
floppy_motorOn();
|
||||
io_delay();
|
||||
|
||||
floppy_setupDMA();
|
||||
io_delay();
|
||||
|
||||
floppy_setmode();
|
||||
io_delay();
|
||||
floppy_sendbyte (FD_READ); //send read command
|
||||
floppy_sendbyte (head*4 + 0);
|
||||
floppy_sendbyte (track); /* Cylinder */
|
||||
floppy_sendbyte (head); /* Head */
|
||||
floppy_sendbyte (sector); /* Sector */
|
||||
floppy_sendbyte (2); /* 0=128, 1=256, 2=512, 3=1024, ... */
|
||||
floppy_sendbyte (18);
|
||||
//floppy_sendbyte (sector+secs-1); /* Last sector in track:here are sectors count */
|
||||
floppy_sendbyte (0x1B);
|
||||
floppy_sendbyte (0xff);
|
||||
return;
|
||||
}
|
||||
|
||||
void init_fd(void)
|
||||
{
|
||||
floppy_get_info();
|
||||
rt_kprintf("Floppy Inc : %s Floppy Type : %s",floppy_inc_name,floppy_type);
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
#ifndef _FLOPPY_H
|
||||
#define _FLOPPY_H
|
||||
|
||||
#define FD_STATUS 0x3f4 // 主状态寄存器端口。
|
||||
#define FD_DATA 0x3f5 // 数据端口。
|
||||
#define FD_DOR 0x3f2 // 数字输出寄存器(也称为数字控制寄存器)。
|
||||
#define FD_DIR 0x3f7 // 数字输入寄存器。
|
||||
#define FD_DCR 0x3f7 // 数据传输率控制寄存器。
|
||||
|
||||
/* 主状态寄存器各比特位的含义 */
|
||||
|
||||
#define STATUS_BUSYMASK 0x0F // 驱动器忙位(每位对应一个驱动器)。
|
||||
#define STATUS_BUSY 0x10 // 软盘控制器忙。
|
||||
#define STATUS_DMA 0x20 // 0 - 为DMA 数据传输模式,1 - 为非DMA 模式。
|
||||
#define STATUS_DIR 0x40 // 传输方向:0 - CPU .. fdc,1 - 相反。
|
||||
#define STATUS_READY 0x80 // 数据寄存器就绪位。
|
||||
|
||||
|
||||
/*状态字节0(ST0)各比特位的含义 */
|
||||
|
||||
#define ST0_DS 0x03 // 驱动器选择号(发生中断时驱动器号)。
|
||||
#define ST0_HA 0x04 // 磁头号。
|
||||
#define ST0_NR 0x08 // 磁盘驱动器未准备好。
|
||||
#define ST0_ECE 0x10 // 设备检测出错(零磁道校准出错)。
|
||||
#define ST0_SE 0x20 // 寻道或重新校正操作执行结束。
|
||||
#define ST0_INTR 0xC0 // 中断代码位(中断原因),00 - 命令正常结束;
|
||||
// 01 - 命令异常结束;10 - 命令无效;11 - FDD 就绪状态改变。
|
||||
|
||||
/*状态字节1(ST1)各比特位的含义 */
|
||||
|
||||
#define ST1_MAM 0x01 // 未找到地址标志(ID AM)。
|
||||
#define ST1_WP 0x02 // 写保护。
|
||||
#define ST1_ND 0x04 // 未找到指定的扇区。
|
||||
#define ST1_OR 0x10 // 数据传输超时(DMA 控制器故障)。
|
||||
#define ST1_CRC 0x20 // CRC 检验出错。
|
||||
#define ST1_EOC 0x80 // 访问超过一个磁道上的最大扇区号。
|
||||
|
||||
/*状态字节2(ST2)各比特位的含义 */
|
||||
|
||||
#define ST2_MAM 0x01 // 未找到数据地址标志。
|
||||
#define ST2_BC 0x02 // 磁道坏。
|
||||
#define ST2_SNS 0x04 // 检索(扫描)条件不满足。
|
||||
#define ST2_SEH 0x08 // 检索条件满足。
|
||||
#define ST2_WC 0x10 // 磁道(柱面)号不符。
|
||||
#define ST2_CRC 0x20 // 数据场CRC 校验错。
|
||||
#define ST2_CM 0x40 // 读数据遇到删除标志。
|
||||
|
||||
/*状态字节3(ST3)各比特位的含义 */
|
||||
|
||||
#define ST3_HA 0x04 // 磁头号。
|
||||
#define ST3_TZ 0x10 // 零磁道信号。
|
||||
#define ST3_WP 0x40 // 写保护。
|
||||
|
||||
|
||||
/* 软盘命令码 */
|
||||
|
||||
#define FD_RECALIBRATE 0x07 // 重新校正(磁头退到零磁道)。
|
||||
#define FD_SEEK 0x0F // 磁头寻道。
|
||||
#define FD_READ 0xE6 // 读数据(MT 多磁道操作,MFM 格式,跳过删除数据)。
|
||||
#define FD_WRITE 0xC5 // 写数据(MT,MFM)。
|
||||
#define FD_SENSEI 0x08 // 检测中断状态。
|
||||
#define FD_SPECIFY 0x03 // 设定驱动器参数(步进速率、磁头卸载时间等)。
|
||||
|
||||
|
||||
/* DMA 命令 */
|
||||
#define DMA_READ 0x46 // DMA 读盘,DMA 方式字(送DMA 端口12,11)。
|
||||
#define DMA_WRITE 0x4A
|
||||
|
||||
extern void init_fd(void);
|
||||
extern void fd_handler(void);
|
||||
|
||||
#endif
|
|
@ -11,6 +11,18 @@ static __inline unsigned char inb(int port)
|
|||
__asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port));
|
||||
return data;
|
||||
}
|
||||
static __inline unsigned char inb_p(unsigned short port)
|
||||
{
|
||||
unsigned char _v;
|
||||
__asm__ __volatile__ ("inb %1, %0\n\t"
|
||||
// "outb %0,$0x80\n\t"
|
||||
// "outb %0,$0x80\n\t"
|
||||
// "outb %0,$0x80\n\t"
|
||||
"outb %0,$0x80"
|
||||
:"=a" (_v)
|
||||
:"d" ((unsigned short) port));
|
||||
return _v;
|
||||
}
|
||||
|
||||
static __inline unsigned short inw(int port)
|
||||
{
|
||||
|
@ -39,11 +51,36 @@ static __inline void outb(int port, unsigned char data)
|
|||
__asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
|
||||
}
|
||||
|
||||
|
||||
static __inline void outb_p(char value, unsigned short port)
|
||||
{
|
||||
__asm__ __volatile__ ("outb %0,%1\n\t"
|
||||
"outb %0,$0x80"
|
||||
::"a" ((char) value),"d" ((unsigned short) port));
|
||||
}
|
||||
|
||||
static __inline void outw(int port, unsigned short data)
|
||||
{
|
||||
__asm __volatile("outw %0,%w1" : : "a" (data), "d" (port));
|
||||
}
|
||||
|
||||
static __inline unsigned char readcmos(int reg)
|
||||
{
|
||||
outb(reg,0x70);
|
||||
return (unsigned char) inb(0x71);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define io_delay() \
|
||||
__asm__ __volatile__ ("pushal \n\t"\
|
||||
"mov $0x3F6, %dx \n\t" \
|
||||
"inb %dx, %al \n\t" \
|
||||
"inb %dx, %al \n\t" \
|
||||
"inb %dx, %al \n\t" \
|
||||
"inb %dx, %al \n\t" \
|
||||
"popal")
|
||||
|
||||
/* Gate descriptors are slightly different*/
|
||||
struct Gatedesc {
|
||||
unsigned gd_off_15_0 : 16; // low 16 bits of offset in segment
|
||||
|
|
Loading…
Reference in New Issue