【问题标题】:How to read blocks from a floppy with sectors?如何从带有扇区的软盘中读取块?
【发布时间】:2012-04-18 18:35:39
【问题描述】:

我需要从预操作系统状态读取软盘,并且我有一个要读取的函数,但它似乎无法读取超过第 4 个扇区...

void get_block(blk, buf) int blk; char buf[]
{
   int cyl, head, sector;

   cyl = ((blk*2) / 18) / 2;
   head = ((blk*2) / 18) % 2;
   sector = (blk*2) % 18;

   // Read first sector <<Dies here if blk > 2>>
   diskr(cyl, head, sector, buf);

   // Increment
   if ((sector = (++sector % 18)) == 0)
      if ((head = (++head % 2)) == 0)
         cyl++;

   // Read second sector <<Dies here if blk == 2>>
   diskr(cyl, head, sector, buf+512);
}

知道为什么吗?我是否错误地从块转换?

【问题讨论】:

  • 哇! ANSI C 之前!好久没看到了……
  • 看看这个问题的第一个代码示例是否有帮助。他还引用了您可能想要在 Google 上搜索的内容:cboard.cprogramming.com/cplusplus-programming/…
  • @DietrichEpp:考虑到手头的任务似乎很合适:D

标签: c block head sector floppy


【解决方案1】:

不,假设您的磁盘是 1.44M 的“软盘”(80 个柱面,2 个磁头/柱面,18 个扇区/磁头,512 字节/扇区),那么这些计算应该没问题,如下面的程序所示:

#include <stdio.h>
int main (void) {
    int blk, cyl, head, sector;
    for (blk = 0; blk <= 18; blk++) {
        cyl = ((blk*2) / 18) / 2;
        head = ((blk*2) / 18) % 2;
        sector = (blk*2) % 18;
        printf ("%2d (a) -> %2d %2d %2d", blk, cyl, head, sector);
        if ((sector = (++sector % 18)) == 0)
            if ((head = (++head % 2)) == 0)
                cyl++;
        printf (" (b) -> %2d %2d %2d\n", cyl, head, sector);
    }
    return 0;
}

其输出为:

 0 (a) ->  0  0  0 (b) ->  0  0  1
 1 (a) ->  0  0  2 (b) ->  0  0  3
 2 (a) ->  0  0  4 (b) ->  0  0  5
 3 (a) ->  0  0  6 (b) ->  0  0  7
 4 (a) ->  0  0  8 (b) ->  0  0  9
 5 (a) ->  0  0 10 (b) ->  0  0 11
 6 (a) ->  0  0 12 (b) ->  0  0 13
 7 (a) ->  0  0 14 (b) ->  0  0 15
 8 (a) ->  0  0 16 (b) ->  0  0 17
 9 (a) ->  0  1  0 (b) ->  0  1  1
10 (a) ->  0  1  2 (b) ->  0  1  3
11 (a) ->  0  1  4 (b) ->  0  1  5
12 (a) ->  0  1  6 (b) ->  0  1  7
13 (a) ->  0  1  8 (b) ->  0  1  9
14 (a) ->  0  1 10 (b) ->  0  1 11
15 (a) ->  0  1 12 (b) ->  0  1 13
16 (a) ->  0  1 14 (b) ->  0  1 15
17 (a) ->  0  1 16 (b) ->  0  1 17
18 (a) ->  1  0  0 (b) ->  1  0  1

有点担心以下行为的未定义性质:

if ((sector = (++sector % 18)) == 0)

构造,喜欢这样的东西:

if ((sector = (sector + 1) % 18)) == 0)

但是,如果它为您提供正确的值,那应该没问题。但是,您需要检查它确实在您运行的环境中为您提供了正确的值。在我的gcc 版本中它确实提供了正确的值。 '这并不意味着它会在你的情况下。

或者您也可以使用上面定义的 建议形式。

您遇到的故障点与磁头或气缸之间的切换相去甚远,因此我认为这不是包装问题,但如果可能的话,您应该打印出环境中的值。

当您说“无法读取第 4 个扇区”时,您应该准确地说明这是什么意思?机器是否死机,是否出现磁盘错误,是否返回您认为垃圾的内容?

磁盘有可能没有正确格式化,或者有故障,也有可能它没有您希望看到的数据。可能值得用 DOS/Windows/whatever 格式化软盘并检查它在您的程序中的作用。

【讨论】:

  • “我有点担心:if ((sector = (++sector % 18)) == 0) 构造”——你应该非常关注它。即使它今天给他和你正确的价值观,明天也不会。或者谁知道呢,也许今天没有给他正确的价值观,也许这就是他的问题。
  • 因此我的评论来检查它们。由于缺少序列点,我不会费心去查看它是否未定义,因为它很容易被更易读的版本(IMNSHO)修复(无论是否需要)。但是我并不太担心它明天不能工作(在以后的编译器上),因为它使用的是 K&R 风格的非原型函数:-)
  • 好的,我认为很明显有两个扇区分配在中间没有序列点。 K&R 没有说哪个任务会“获胜”。
  • @paxdiablo 我的意思是,当我读入组描述符(block 2,Cyl 0,head 0,sec 4-5)时,get_block 将在第 4 个扇区读取块然后在diskr()处冻结。 _windows 我有打印语句表明我得到了正确的值
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-17
  • 2020-10-11
  • 2013-07-15
  • 2020-02-03
  • 2023-03-23
  • 2013-11-20
相关资源
最近更新 更多