summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bsp/x86/applications/application.c125
-rw-r--r--bsp/x86/drivers/dma.h187
-rw-r--r--bsp/x86/drivers/floppy.c360
-rw-r--r--bsp/x86/drivers/floppy.h71
-rw-r--r--bsp/x86/drivers/include/bsp.h11
-rw-r--r--bsp/x86/drivers/include/i386.h35
6 files changed, 714 insertions, 75 deletions
diff --git a/bsp/x86/applications/application.c b/bsp/x86/applications/application.c
index 0883216976..3a2f6c9b82 100644
--- a/bsp/x86/applications/application.c
+++ b/bsp/x86/applications/application.c
@@ -1,100 +1,77 @@
-/** File : application.c
+/*
+ * File : application.c
* This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2012, RT-Thread Develop Team
+ * COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://openlab.rt-thread.com/license/LICENSE
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
-
-* Change Logs:
+ * This program 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
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
* Date Author Notes
- * 2006-09-15 QiuYi the first version
- */
-
-/**
- * @addtogroup QEMU
+ * 2009-01-05 Bernard the first version
*/
-/*@{*/
-
#include <rtthread.h>
-ALIGN(RT_ALIGN_SIZE)
-static char thread_led1_stack[1024];
-struct rt_thread thread_led1;
-static void rt_thread_entry_led1(void *parameter)
+#ifdef RT_USING_DFS
+#include <dfs_fs.h>
+#include "floppy.h"
+#endif
+
+/* components initialization for simulator */
+void components_init(void)
{
- unsigned int count=0;
+#ifdef RT_USING_DFS
+ rt_floppy_init();
+ /* initialize the device file system */
+ dfs_init();
- while (1)
- {
- /* led1 on */
-#ifndef RT_USING_FINSH
- rt_kprintf("led1 on,count : %d\r\n",count);
+#ifdef RT_USING_DFS_ELMFAT
+ /* initialize the elm chan FatFS file system*/
+ elm_init();
#endif
- count ++;
- /* sleep 0.5 second and switch to other thread */
- rt_thread_delay(RT_TICK_PER_SECOND / 2);
-
- /* led1 off */
-#ifndef RT_USING_FINSH
- rt_kprintf("led1 off\r\n");
#endif
- rt_thread_delay(RT_TICK_PER_SECOND / 2);
- }
}
-
-ALIGN(RT_ALIGN_SIZE)
-static char thread_led2_stack[1024];
-struct rt_thread thread_led2;
-void rt_thread_entry_led2(void *parameter)
+void rt_init_thread_entry(void *parameter)
{
- unsigned int count=0;
+ components_init();
- while (1)
+ /* File system Initialization */
+#ifdef RT_USING_DFS
{
- /* led2 on */
-#ifndef RT_USING_FINSH
- rt_kprintf("led2 on,count : %d\r\n",count);
-#endif
- count ++;
- rt_thread_delay(RT_TICK_PER_SECOND);
- /* led2 off */
-#ifndef RT_USING_FINSH
- rt_kprintf("led2 off\r\n");
+#ifdef RT_USING_DFS_ELMFAT
+ /* mount sd card fatfs as root directory */
+ if (dfs_mount("floppy", "/", "elm", 0, 0) == 0)
+ rt_kprintf("fatfs initialized!\n");
+ else
+ rt_kprintf("fatfs initialization failed!\n");
#endif
- rt_thread_delay(RT_TICK_PER_SECOND);
}
+#endif
}
-/**
- * This function will be invoked to initalize user application when system
- * startup.
- */
-
-int rt_application_init(void)
+int rt_application_init()
{
- // init led1 thread
- rt_thread_init(&thread_led1,
- "led1",
- rt_thread_entry_led1,
- RT_NULL,
- &thread_led1_stack[0],
- sizeof(thread_led1_stack),11,5);
- rt_thread_startup(&thread_led1);
+ rt_thread_t tid;
- // init led2 thread
- rt_thread_init(&thread_led2,
- "led2",
- rt_thread_entry_led2,
- RT_NULL,
- &thread_led2_stack[0],
- sizeof(thread_led2_stack),12,5);
- rt_thread_startup(&thread_led2);
+ tid = rt_thread_create("init",
+ rt_init_thread_entry, RT_NULL,
+ 2048, RT_THREAD_PRIORITY_MAX / 3, 20);
+
+ if (tid != RT_NULL)
+ rt_thread_startup(tid);
return 0;
}
-
-/*@}*/
diff --git a/bsp/x86/drivers/dma.h b/bsp/x86/drivers/dma.h
new file mode 100644
index 0000000000..f1a8563cb1
--- /dev/null
+++ b/bsp/x86/drivers/dma.h
@@ -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
+
diff --git a/bsp/x86/drivers/floppy.c b/bsp/x86/drivers/floppy.c
new file mode 100644
index 0000000000..058bf1b941
--- /dev/null
+++ b/bsp/x86/drivers/floppy.c
@@ -0,0 +1,360 @@
+
+#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;
+
+#define OUTB(v,p) outb(p,v)
+
+#include "floppy.h"
+#include "dma.h"
+
+#define NULL RT_NULL
+#define SECTOR_SIZE 512
+#define panic(str,...) do { rt_kprintf("panic::" str,##__VA_ARGS__); while(1); } while(0)
+
+#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 u32 floppy_size =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";
+ floppy_size = 2458*512;
+ break;
+
+ case 0x04: // 1.44MB 标准软盘
+ floppy_type = "1.44MB";
+ floppy_size = 2880*512;
+ break;
+
+ case 0x05: // 2.88MB
+ floppy_type = "2.88MB";
+ floppy_size = 2*2880*512;
+ 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,&sector);
+
+ 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;
+}
+
+static struct rt_device devF;
+static struct rt_mutex lock;
+static struct rt_semaphore sem;
+
+/* RT-Thread device interface */
+
+static rt_err_t rt_floppy_init_internal(rt_device_t dev)
+{
+ return RT_EOK;
+}
+
+static rt_err_t rt_floppy_open(rt_device_t dev, rt_uint16_t oflag)
+{
+ return RT_EOK;
+}
+
+static rt_err_t rt_floppy_close(rt_device_t dev)
+{
+ return RT_EOK;
+}
+
+/* position: block page address, not bytes address
+ * buffer:
+ * size : how many blocks
+ */
+static rt_size_t rt_floppy_read(rt_device_t device, rt_off_t position, void *buffer, rt_size_t size)
+{
+ rt_size_t doSize = size;
+
+ rt_mutex_take(&lock, RT_WAITING_FOREVER);
+ while(size>0)
+ {
+ floppy_read_cmd(position);
+
+ rt_sem_take(&sem, RT_WAITING_FOREVER); /* waiting isr sem forever */
+
+ floppy_result();
+ io_delay();
+
+ if(ST1 != 0 || ST2 != 0)
+ {
+ panic("ST0 %d ST1 %d ST2 %d\n",ST0,ST1,ST2);
+ }
+
+ rt_memcpy(buffer, floppy_buffer, 512);
+
+ floppy_motorOff();
+ io_delay();
+
+ position += 1;
+ size -= 1;
+ }
+ rt_mutex_release(&lock);
+
+ return doSize;
+}
+
+/* position: block page address, not bytes address
+ * buffer:
+ * size : how many blocks
+ */
+static rt_size_t rt_floppy_write(rt_device_t device, rt_off_t position, const void *buffer, rt_size_t size)
+{
+ rt_mutex_take(&lock, RT_WAITING_FOREVER);
+ panic("FIXME:I don't know how!\n");
+ rt_mutex_release(&lock);
+ return size;
+}
+
+static rt_err_t rt_floppy_control(rt_device_t dev, rt_uint8_t cmd, void *args)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
+ {
+ struct rt_device_blk_geometry *geometry;
+
+ geometry = (struct rt_device_blk_geometry *)args;
+ if (geometry == RT_NULL) return -RT_ERROR;
+
+ geometry->bytes_per_sector = SECTOR_SIZE;
+ geometry->block_size = SECTOR_SIZE;
+
+ geometry->sector_count = floppy_size / SECTOR_SIZE;
+ }
+
+ return RT_EOK;
+}
+
+static void rt_floppy_isr(int vector, void* param)
+{
+ (void)vector;
+ (void)param;
+ rt_sem_release(&sem);
+}
+
+void rt_floppy_init(void)
+{
+ struct rt_device *device;
+
+ rt_mutex_init(&lock,"fdlock", RT_IPC_FLAG_FIFO);
+ rt_sem_init(&sem, "fdsem", 0, RT_IPC_FLAG_FIFO);
+
+ rt_hw_interrupt_install(FLOPPY_IRQ, rt_floppy_isr, RT_NULL, "floppy");
+ rt_hw_interrupt_umask(FLOPPY_IRQ);
+
+ floppy_get_info();
+ rt_kprintf("Floppy Inc : %s Floppy Type : %s\n",floppy_inc_name,floppy_type);
+
+ device = &(devF);
+
+ device->type = RT_Device_Class_Block;
+ device->init = rt_floppy_init_internal;
+ device->open = rt_floppy_open;
+ device->close = rt_floppy_close;
+ device->read = rt_floppy_read;
+ device->write = rt_floppy_write;
+ device->control = rt_floppy_control;
+ device->user_data = NULL;
+
+ rt_device_register(device, "floppy",
+ RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
+
+}
diff --git a/bsp/x86/drivers/floppy.h b/bsp/x86/drivers/floppy.h
new file mode 100644
index 0000000000..f619508c43
--- /dev/null
+++ b/bsp/x86/drivers/floppy.h
@@ -0,0 +1,71 @@
+#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 rt_floppy_init(void);
+
+#endif
diff --git a/bsp/x86/drivers/include/bsp.h b/bsp/x86/drivers/include/bsp.h
index 908c721661..724f518c6e 100644
--- a/bsp/x86/drivers/include/bsp.h
+++ b/bsp/x86/drivers/include/bsp.h
@@ -74,7 +74,16 @@ extern "C" {
#define INTTIMER0 0
#define INTKEYBOARD 1
#define INTUART0_RX 4
-
+#define CLOCK_IRQ 0
+#define KEYBOARD_IRQ 1
+#define CASCADE_IRQ 2 /* cascade enable for 2nd AT controller */
+#define ETHER_IRQ 3 /* default ethernet interrupt vector */
+#define SECONDARY_IRQ 3 /* RS232 interrupt vector for port 2 */
+#define RS232_IRQ 4 /* RS232 interrupt vector for port 1 */
+#define XT_WINI_IRQ 5 /* xt winchester */
+#define FLOPPY_IRQ 6 /* floppy disk */
+#define PRINTER_IRQ 7
+#define AT_WINI_IRQ 14 /* at winchester */
/* I/O Addresses of the two 8259A programmable interrupt controllers */
#define IO_PIC1 0x20 /* Master(IRQs 0-7) */
#define IO_PIC2 0xa0 /* Slave(IRQs 8-15) */
diff --git a/bsp/x86/drivers/include/i386.h b/bsp/x86/drivers/include/i386.h
index fe023d754a..68c854932b 100644
--- a/bsp/x86/drivers/include/i386.h
+++ b/bsp/x86/drivers/include/i386.h
@@ -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,34 @@ 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(0x70,reg);
+ 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