******************** * CF卡/HDD硬盘驱动 * ******************** 2007/07/30 asdjf@163.com www.armecos.com CF卡驱动(兼容硬盘驱动)是相当简单的,主要内容就是读写扇区,也就是数据块,我们称之为块设备驱动。基于分层思想,块驱动部分不考虑数据格式,只负责实现机制,具体的数据解释交由上层文件系统负责,这样一来,就没有什么太多内容了,分层处理就是好啊!块设备具有移动特性,支持热插拔,所以,就存在一个在位探测和身份识别问题。当然,驱动还必须符合ecos要求。 《ecos增值包》提供了大量支撑软件模块,使得初学者能把精力集中在CF卡驱动上,而不必在其他细节上浪费时间。例如:ecos库负责初始化硬件;不必自己编写串口操作,需要输出信息时只要printf即可;精确的延时函数,使用定时器实现而不是多重循环,ecos负责复杂的计算和烦琐的定时器操作。 下面详细介绍CF卡驱动编写。 ----------------- 端口输入/输出操作 ----------------- CF卡驱动中最基本的操作就是端口输入/输出,用于访问地址映射的寄存器,数据位宽8位/16位,满足ATA接口/总线时序。
#define HAL_IDE_READ_UINT8(ctrl, reg, val) do{ HAL_WRITE_UINT16(ATA_EN|ATA_ALE|reg, 0); HAL_READ_UINT16(ATA_EN|ATA_RW, val); HAL_WRITE_UINT16(ATA_EN|ATA_ALE|ATA_OUT|ATA_CS1|ATA_CS0, 0); }while(0) #define HAL_IDE_WRITE_UINT8(ctrl, reg, val) do{ HAL_WRITE_UINT16(ATA_EN|ATA_ALE|ATA_OUT|reg, 0); HAL_WRITE_UINT16(ATA_EN|ATA_RW, val); HAL_WRITE_UINT16(ATA_EN|ATA_ALE|ATA_OUT|ATA_CS1|ATA_CS0, 0); }while(0)
#define HAL_IDE_READ_UINT16(ctrl, reg, val) do{ HAL_WRITE_UINT16(ATA_EN|ATA_ALE|reg, 0); HAL_READ_UINT16(ATA_EN|ATA_RW, val); HAL_WRITE_UINT16(ATA_EN|ATA_ALE|ATA_OUT|ATA_CS1|ATA_CS0, 0); }while(0) #define HAL_IDE_WRITE_UINT16(ctrl, reg, val) do{ HAL_WRITE_UINT16(ATA_EN|ATA_ALE|ATA_OUT|reg, 0); HAL_WRITE_UINT16(ATA_EN|ATA_RW, val); HAL_WRITE_UINT16(ATA_EN|ATA_ALE|ATA_OUT|ATA_CS1|ATA_CS0, 0); }while(0) 参数ctrl用于区分IDE控制器,有些设备支持2个IDE口,每个口支持主/从两块硬盘,控制器挂在PCI总线上,驱动程序需要知道控制器号和主从选择才能具体定位一块硬盘。
reg是寄存器地址。 // IDE Register Indices #define IDE_REG_DATA 0x20 //0 #define IDE_REG_ERROR 0x22 //1 #define IDE_REG_FEATURES 0x22 //1 #define IDE_REG_COUNT 0x24 //2 #define IDE_REG_REASON 0x24 //2 // ATAPI #define IDE_REG_LBALOW 0x26 //3 #define IDE_REG_LBAMID 0x28 //4 #define IDE_REG_LBAHI 0x2A //5 #define IDE_REG_DEVICE 0x2C //6 #define IDE_REG_STATUS 0x2E //7 #define IDE_REG_COMMAND 0x2E //7
注意:板子的A1接IDE的A0,还有CS0/CS1也映射到地址里了,所以右边注释掉的是手册给出的值,真正用到的是修正后的地址值。 数据位宽支持8位/16位,所以分别提供读写接口。 do...while(0)是用于宏定义的一种方法,它把若干条语句合成一条语句。注意这里用的是宏,这4条语句频繁调用,严重影响效率,而且不大,所以用宏替换而不是语句,这样可以提高效率又不会造成太大的存储空间浪费。 因为开发板是用扩展电路模拟ATA时序,没有直接连接MCU和ATA总线,所以,需要用3条语句实现读写功能,略显烦琐。如果硬件支持,用单条语句实现甚好。 注意函数命名规则符合ecos规范,例如:HAL_IDE_READ_UINT8。HAL说明这是一个硬件抽象层函数,与硬件相关,IDE说明与IDE硬件设备相关,READ表明是个读操作,UINT8表示位宽为8bit,无符号整数类型。这样的写法含义一目了然,又不会重名,造成名字污染,更不会让我们费脑子琢磨如何起名字。类似这样的细节在《ecos增值包》里还有很多,就不一一指明了,多思考多体会就能从中学到不少东西。 -------- 等待操作 -------- CF卡/硬盘都是慢速设备,MCU发出请求后不能立即响应,需要等待。所谓等待就是判断状态位(有些支持超时退出)。 static inline void __wait_for_ready(int ctlr) { cyg_uint8 status; do { HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, status); } while (status & (IDE_STAT_BSY | IDE_STAT_DRQ)); }
// Wait while the device is busy with the last command static inline int __wait_busy(int ctlr) { cyg_uint8 status; cyg_ucount32 tries; for (tries=0; tries < 1000000; tries++) { CYGACC_CALL_IF_DELAY_US(10); HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, status); if ((status & IDE_STAT_BSY) == 0) return 1; } return 0; }
static inline int __wait_for_drq(int ctlr) { cyg_uint8 status; cyg_ucount32 tries;
for (tries=0; tries<1000000; tries++) { CYGACC_CALL_IF_DELAY_US(10); HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, status); if (!(status & IDE_STAT_BSY)) { if (status & IDE_STAT_DRQ) return 1; else return 0; } } return 0; }
注意这些函数前面都有inline关键字,就是说尽可能替换而不要调用函数。因为这些等待函数会被频繁调用,所以用替换可以提高效率。 状态寄存器里提供多种状态指示,用得比较多的是BSY和DRQ。 #define IDE_STAT_BSY 0x80 #define IDE_STAT_DRDY 0x40 #define IDE_STAT_SERVICE 0x10 #define IDE_STAT_DRQ 0x08 #define IDE_STAT_CORR 0x04 #define IDE_STAT_ERR 0x01
延时函数使用ecos提供的CYGACC_CALL_IF_DELAY_US,它是用定时器实现的微秒级延时,非常精确,可移植(多重循环在不同频率机器上需要重新计算,而且由于多级流水线等加速措施导致不能精确计算耗时)。用户只要填写想要延时的微秒数即可。注意:受限于定时器计数器位宽,太大的延时可能溢出,这个函数适于短延时。 -------- 在位判断 -------- 块设备可能被移动,所以需要随时检测是否在位。方法是向设备/磁头寄存器里写入数据再读出,若一致即表明设备在位,否则说明没有设备存在。这个寄存器可读写并保存数据,所以就不必使用额外的GPIO探测线了。只要主从有一个在位就返回确认,如果是在VMWARE里仿真,就固定使用虚拟的主设备。我只在开发板上接一个CF卡,所以这个函数能正常工作。 static int ide_presence_detect(int ctlr) { cyg_uint8 sel, val; int i;
for (i = 0; i < 2; i++) { sel = (i << 4) | 0xA0; CYGACC_CALL_IF_DELAY_US((cyg_uint32)50000); HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, sel); CYGACC_CALL_IF_DELAY_US((cyg_uint32)50000); HAL_IDE_READ_UINT8(ctlr, IDE_REG_DEVICE, val); if (val == sel) { #ifndef CYGSEM_DEVS_DISK_IDE_VMWARE if (i) HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, 0); #endif return 1; } } return 0; }
-------- 复位操作 -------- 硬盘初始工作前要先进入一个确定状态,方法是拉低ATA_RST引脚一段时间,然后置高并判断状态是否就绪。 static int ide_reset(int ctlr) { cyg_uint8 status; int delay, i; int tmp;
HAL_READ_UINT32(LPC2XXX_GPIO_IO2DIR, tmp); tmp |= ATA_RST; tmp &= (~ATA_CD); //可不用 HAL_WRITE_UINT32(LPC2XXX_GPIO_IO2DIR, tmp); HAL_WRITE_UINT32(LPC2XXX_GPIO_IO2CLR, ATA_RST); cyg_thread_delay(1); HAL_WRITE_UINT32(LPC2XXX_GPIO_IO2SET, ATA_RST); printf("IDE Reset!
"); // wait 30 seconds max for not busy and drive ready for (delay = 0; delay < 300; ++delay) { for(i = 0; i < 100; i++){ CYGACC_CALL_IF_DELAY_US((cyg_uint32)1000); //yynote 延时不能太长,否则微秒延时函数无法正常工作 HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, status); if (!(status & IDE_STAT_BSY)) { if (status & IDE_STAT_DRDY) { return 1; } } } } return 0; }
-------- 设备识别 -------- 每个卡或硬盘都有自己的参数信息,通过ECH命令可以读出来,其格式如ide_identify_data_t结构体所示。我们可以通过这些信息了解设备情况以及确定是否能够操作它。当然,CF驱动只管读出数据存放到buf里,它不关心这个数据结构的。cyg_uint16表示cygnus公司定义的16位无符号整数,用它定义数据类型的程序移植性好。注意数据都是通过16位数据总线读出来的,命令才用8位的读写函数,这样数据吞吐量大。 typedef struct ide_identify_data_t_ { cyg_uint16 general_conf; // 00 : general configuration cyg_uint16 num_cylinders; // 01 : number of cylinders (default CHS trans) cyg_uint16 reserved0; // 02 : reserved cyg_uint16 num_heads; // 03 : number of heads (default CHS trans) cyg_uint16 num_ub_per_track; // 04 : number of unformatted bytes per track cyg_uint16 num_ub_per_sector; // 05 : number of unformatted bytes per sector cyg_uint16 num_sectors; // 06 : number of sectors per track (default CHS trans) cyg_uint16 num_card_sectors[2]; // 07-08 : number of sectors per card cyg_uint16 reserved1; // 09 : reserved cyg_uint16 serial[10]; // 10-19 : serial number (string) cyg_uint16 buffer_type; // 20 : buffer type (dual ported) cyg_uint16 buffer_size; // 21 : buffer size in 512 increments cyg_uint16 num_ECC_bytes; // 22 : number of ECC bytes passed on R/W Long cmds cyg_uint16 firmware_rev[4]; // 23-26 : firmware revision (string) cyg_uint16 model_num[20]; // 27-46 : model number (string) cyg_uint16 rw_mult_support; // 47 : max number of sectors on R/W multiple cmds cyg_uint16 reserved2; // 48 : reserved cyg_uint16 capabilities; // 49 : LBA, DMA, IORDY support indicator cyg_uint16 reserved3; // 50 : reserved cyg_uint16 pio_xferc_timing; // 51 : PIO data transfer cycle timing mode cyg_uint16 dma_xferc_timing; // 52 : single word DMA data transfer cycle timing mode cyg_uint16 cur_field_validity; // 53 : words 54-58 validity (0 == not valid) cyg_uint16 cur_cylinders; // 54 : number of current cylinders cyg_uint16 cur_heads; // 55 : number of current heads cyg_uint16 cur_spt; // 56 : number of current sectors per track cyg_uint16 cur_capacity[2]; // 57-58 : current capacity in sectors cyg_uint16 mult_sectors; // 59 : multiple sector setting cyg_uint16 lba_total_sectors[2]; // 60-61 : total sectors in LBA mode cyg_uint16 sw_dma; // 62 : single word DMA support cyg_uint16 mw_dma; // 63 : multi word DMA support cyg_uint16 apio_modes; // 64 : advanced PIO transfer mode supported cyg_uint16 min_dma_timing; // 65 : minimum multiword DMA transfer cycle cyg_uint16 rec_dma_timing; // 66 : recommended multiword DMA cycle cyg_uint16 min_pio_timing; // 67 : min PIO transfer time without flow control cyg_uint16 min_pio_iordy_timing; // 68 : min PIO transfer time with IORDY flow control // cyg_uint16 reserved4[187]; // 69-255: reserved } ide_identify_data_t;
static int ide_ident(int ctlr, int dev, cyg_uint16 *buf) { int i;
if (!__wait_busy(ctlr)) { return 0; } HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, dev << 4); HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COMMAND, 0xEC); CYGACC_CALL_IF_DELAY_US((cyg_uint32)50000);
if (!__wait_for_drq(ctlr)) { return 0; } for (i = 0; i < (CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE / sizeof(cyg_uint16)); i++, buf++) HAL_IDE_READ_UINT16(ctlr, IDE_REG_DATA, *buf);
return 1; }
-------- 读写扇区 -------- 最主要的工作内容,最好基于DMA和中断操作,本板采用普通操作。写和读类似,略。 static int ide_read_sector(int ctlr, int dev, cyg_uint32 start, cyg_uint8 *buf, cyg_uint32 len) { int j, c; cyg_uint16 p; cyg_uint8 * b=buf;
if(!__wait_busy(ctlr)) { return 0; } HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COUNT, 1); // count =1 HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBALOW, start & 0xff); HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBAMID, (start >> 8) & 0xff); HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBAHI, (start >> 16) & 0xff); HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, ((start >> 24) & 0xf) | (dev << 4) | 0x40); HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COMMAND, 0x20);
if (!__wait_for_drq(ctlr)) return 0; for (j = 0, c=0 ; j < (CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE / sizeof(cyg_uint16)); j++) { HAL_IDE_READ_UINT16(ctlr, IDE_REG_DATA, p); if (c++<len) *b++=p&0xff; if (c++<len) *b++=(p>>8)&0xff; } return 1; }
ctrl是控制器号,dev是主从选择,start是扇区号,buf是数据缓冲区,len 是操作长度。 使用下面语句可以读出指定硬盘上的指定扇区数据到buf里。示例:读第一个IDE口的主硬盘的0扇区。 if(!ide_read_sector(0, 0, 0, buf, 512)){ printf("ide_read_sector ERROR!
"); } -------------- 可视化设备信息 -------------- 设备识别信息的可视化。
static void ide_disk_info(void) { cyg_uint32 id_buf[CYGDAT_DEVS_DISK_IDE_SECTOR_SIZE/sizeof(cyg_uint32)]; ide_identify_data_t *ide_idData=(ide_identify_data_t*)id_buf; char buf[50]; if (!ide_ident(0, 0, (cyg_uint16 *)id_buf)) { printf("IDE ident DRQ error
"); }
id_strcpy(buf, ide_idData->serial, 20); printf(" Serial : %s
", buf); id_strcpy(buf, ide_idData->firmware_rev, 8); printf(" Firmware rev. : %s
", buf); id_strcpy(buf, ide_idData->model_num, 40); printf(" Model : %s
", buf); printf(" C/H/S : %d/%d/%d
", ide_idData->num_cylinders, ide_idData->num_heads, ide_idData->num_sectors); printf(" LBA sector number: %d
", (ide_idData->lba_total_sectors[1] << 16 | ide_idData->lba_total_sectors[0])); printf(" Kind : %x
", (ide_idData->general_conf>>8)&0x1f);
} 通过以上这些程序就可以随意操作CF卡了,完整程序在光盘里,用任何一个库编译都可以,推荐lpc_default_ram_install,这个库体积小,在RAM里运行,配合redboot,调试起来很方便。注意JP7、JP11跳线要设置正确。
CF卡驱动测试报告
一张512M的CF卡,格式化成FAT16,创建一个a.txt文件,内容为 123 abc
用winhex软件分析,根目录位于439扇区,a.txt文件位于525扇区,当然启动部分就固定在0扇区。 下面是用CF卡驱动读出的识别信息、0扇区数据、439扇区数据、525扇区数据,和winhex的数据对比,完全一致。 识别信息是通过设备识别指令0xEC得到的,它的结构就是ide_identify_data_t结构体所描述的那样。 0、493、525扇区的内容是通过读扇区指令0x20获得的,boot扇区0可对照书上讲解详细分析;root根目录扇区439目前只有一个目录项,格式见书中相关部分,其他未用到的部分为0;a.txt文件扇区525是文件的实体数据,即“123<回车>abc”。
test by yangyi 2007/07/30
+
******************************* * CF Card Test * *******************************
CF card experiment...
IDE Reset!
Print IDE information:
Serial : 00000006090000000497 Firmware rev. : Ver1.27 Model : CF/512 C/H/S : 999/16/63 LBA sector number: 1006992 Kind : 4
info: ----------------------------------------------------------------
0 8a 84 e7 3 0 0 10 0 0 7e 0 2 3f 0 f 0 10 90 5d 0 0 30 30 30 30 30 30 36 30 39 30 30 30 20 30 30 30 30 34 30 37 39 2 0 2 0 4 0 65 56 30 31 72 32 2e 20 37 46 43 35 2f 32 31 20 20 20 20 40 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 50 20 20 20 20 20 20 20 20 20 20 20 20 20 20 1 0 60 0 0 0 3 0 0 0 2 0 0 7 0 e7 3 10 0 70 3f 0 90 5d f 0 0 1 90 5d f 0 0 0 7 4 80 3 0 78 0 78 0 78 0 78 0 0 0 0 0 0 0 90 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 a0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 b0 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 c0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 d0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 e0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 f0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 100 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 110 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 120 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 130 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 140 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 150 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 160 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 170 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 180 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 190 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1a0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1b0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1c0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1d0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1e0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1f0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
----------------------------------------------------------------
0 sector info(0 sec : boot): ----------------------------------------------------------------
0 eb 3c 90 4d 53 44 4f 53 35 2e 30 0 2 10 1 0 10 2 0 2 0 0 f8 f6 0 3f 0 ff 0 0 0 0 0 20 90 5d f 0 0 0 29 8d 3e 1a 8 4e 4f 20 4e 41 30 4d 45 20 20 20 20 46 41 54 31 36 20 20 20 33 c9 40 8e d1 bc f0 7b 8e d9 b8 0 20 8e c0 fc bd 0 7c 50 38 4e 24 7d 24 8b c1 99 e8 3c 1 72 1c 83 eb 3a 60 66 a1 1c 7c 26 66 3b 7 26 8a 57 fc 75 6 80 ca 70 2 88 56 2 80 c3 10 73 eb 33 c9 8a 46 10 98 f7 80 66 16 3 46 1c 13 56 1e 3 46 e 13 d1 8b 76 11 90 60 89 46 fc 89 56 fe b8 20 0 f7 e6 8b 5e b 3 a0 c3 48 f7 f3 1 46 fc 11 4e fe 61 bf 0 0 e8 e6 b0 0 72 39 26 38 2d 74 17 60 b1 b be a1 7d f3 a6 c0 61 74 32 4e 74 9 83 c7 20 3b fb 72 e6 eb dc a0 d0 fb 7d b4 7d 8b f0 ac 98 40 74 c 48 74 13 b4 e e0 bb 7 0 cd 10 eb ef a0 fd 7d eb e6 a0 fc 7d eb f0 e1 cd 16 cd 19 26 8b 55 1a 52 b0 1 bb 0 0 e8 100 3b 0 72 e8 5b 8a 56 24 be b 7c 8b fc c7 46 f0 110 3d 7d c7 46 f4 29 7d 8c d9 89 4e f2 89 4e f6 c6 120 6 96 7d cb ea 3 0 0 20 f b6 c8 66 8b 46 f8 130 66 3 46 1c 66 8b d0 66 c1 ea 10 eb 5e f b6 c8 140 4a 4a 8a 46 d 32 e4 f7 e2 3 46 fc 13 56 fe eb 150 4a 52 50 6 53 6a 1 6a 10 91 8b 46 18 96 92 33 160 d2 f7 f6 91 f7 f6 42 87 ca f7 76 1a 8a f2 8a e8 170 c0 cc 2 a cc b8 1 2 80 7e 2 e 75 4 b4 42 180 8b f4 8a 56 24 cd 13 61 61 72 b 40 75 1 42 3 190 5e b 49 75 6 f8 c3 41 bb 0 0 60 66 6a 0 eb 1a0 b0 4e 54 4c 44 52 20 20 20 20 20 20 d a 4e 54 1b0 4c 44 52 20 69 73 20 6d 69 73 73 69 6e 67 ff d 1c0 a 44 69 73 6b 20 65 72 72 6f 72 ff d a 50 72 1d0 65 73 73 20 61 6e 79 20 6b 65 79 20 74 6f 20 72 1e0 65 73 74 61 72 74 d a 0 0 0 0 0 0 0 0 1f0 0 0 0 0 0 0 0 0 0 0 0 ac bf cc 55 aa
----------------------------------------------------------------
0 sector info(493 sec : root dir): ----------------------------------------------------------------
0 41 20 20 20 20 20 20 20 54 58 54 20 18 2c 7a 40 10 3e 36 3e 36 0 0 52 40 3e 36 2 0 8 0 0 0 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 30 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 40 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 50 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 60 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 70 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 80 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 90 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 a0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 b0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 c0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 d0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 e0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 f0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 100 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 110 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 120 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 130 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 140 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 150 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 160 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 170 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 180 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 190 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1a0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1b0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1c0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1d0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1e0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1f0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
----------------------------------------------------------------
0 sector info(525 sec : a.txt): ----------------------------------------------------------------
0 31 32 33 d a 61 62 63 0 0 0 0 0 0 0 0 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 30 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 40 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 50 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 60 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 70 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 80 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 90 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 a0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 b0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 c0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 d0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 e0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 f0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 100 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 110 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 120 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 130 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 140 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 150 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 160 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 170 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 180 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 190 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1a0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1b0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1c0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1d0 0 0 0 0 0 0 0 0 0 0 0 0  |