ウォンツテック

そでやまのーと

OS作成

読み込みに続いてqemu&実機でのFDC seekと書き込みに成功。
これはdmaの転送方向を変えるのとseekとwrite用コマンドを書くだけでいいのですぐ出来た。
とりあえず直近の目標の一つであるFDCの1セクタ読み書きが出来た。複数セクタ読み書きはこれを適当にwrapすればいいのでとりあえず放置。
次の目標はデバッグ出力用にvgaのprintf的なAPIを書くのとプロセス回りに取り掛かるかな。

write部分のコードは以下の感じ

floppy.c

static void init_dma_w()
{
  fdc_dma_stop();

  out8(DMA_MSR_CLR_SEC, 0x00);
  out8(DMA_CLR_FLP_SEC, 0);

  out8(DMA_MOD_SEC, 0x4a);  // memory >> I/O
  disableInterrupt();
  out8(DMA_ADD_SEC, dma_trans.addr >> 0);
  out8(DMA_ADD_SEC, dma_trans.addr >> 8);
  out8(DMA_TOP, dma_trans.addr >> 16);
  out8(DMA_CNT_SEC, dma_trans.count >> 0);
  out8(DMA_CNT_SEC, dma_trans.count >> 8);
  enableInterrupt();
  fdc_dma_start();
}

static int fdc_seek(u_int8_t track)
{
  u_int8_t cmd[] = {
    CMD_SEEK,       // 0x0f
    0,
    track
  };

  fdc_clear_interrupt();

  sysPrints("[FDC] seek cmd check.\n");
  if (!fdc_cmd(cmd, sizeof(cmd))) {
    sysPrints("[FDC] seek cmd error\n");
    return FALSE;
  }
  sysPrints("[FDC] seek cmd check [OK]\n");

  if (!fdc_wait_interrupt()) {
    sysPrints("[FDC][SEEK] wait interrupt error\n");
    return FALSE;
  }

  /* get result */
  if (!fdc_sense_interrupt()) {
    sysPrints("[FDC][SEEK] SIS error\n");
    return FALSE;
  }

  return TRUE;
}

int fdc_write(char* buf, u_int8_t head, u_int8_t track, u_int8_t sector)
{
  if (!fdc_recalibrate()) {
    sysPrints("[FDC][WRITE] recalibrate error\n");
    return FALSE;
  }

  if (!fdc_seek(track)) {
    sysPrints("[FDC][WRITE] seek error\n");
    return FALSE;
  }

  int i;
  for (i = 0; buf[i] != '\0' || i < 512; i++) {
    dma_databuf[i] = buf[i];
  }

  init_dma_w();

  u_int8_t cmd[] = {
    CMD_WRITE,
    head << 2,      // head
    track,          // track
    head,           // head
    sector,         // sector
    0x2,            // sector length (0x2 = 512byte)
    0x12,           // end of track (EOT)
    0x1b,           // dummy GSR
    0               // dummy STP
  };

  fdc_clear_interrupt();

  if (!fdc_cmd(cmd, sizeof(cmd))) {
    sysPrints("[FDC][WRITE] cmd error\n");
    return FALSE;
  }

  if (!fdc_wait_interrupt()) {
    sysPrints("[FDC][WRITE] wait interrupt error\n");
    return FALSE;
  }

  if (!fdc_read_results()) {
    sysPrints("[FDC][WRITE] read result error\n");
    return FALSE;
  }

  return TRUE;
}

kernel.c

テストコード

  // FDC test
  //fdc_read(0, 8, 1); // head, track, sector
  char buf[] = { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE };
  fdc_write(buf, 0, 8, 9); // buf, head, track, sector

  fdc_read(0, 8, 9);