--- nono/vm/fdc.cpp 2026/04/29 17:04:32 1.1.1.3 +++ nono/vm/fdc.cpp 2026/04/29 17:04:44 1.1.1.6 @@ -1,12 +1,15 @@ // // nono -// Copyright (C) 2017 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // #include "fdc.h" -#include "iocon.h" +#include "pedec.h" #include "scheduler.h" +std::unique_ptr gFDC; + // コンストラクタ FDCDevice::FDCDevice() { @@ -29,41 +32,42 @@ void FDCDevice::ResetHard() { // XXX 他には + event.Stop(); idle_phase(); } uint64 -FDCDevice::Read8(uint32 addr) +FDCDevice::Read(uint32 addr) { - uint32 offset = addr - baseaddr; - switch (offset) { - case 1: + gMPU->AddCycle(19); // InsideOut p.135 + + switch (addr) { + case 0: return ReadStatus(); - case 3: + case 1: return ReadData(); - case 5: + case 2: return ReadDriveStatus(); - default: - break; + case 3: + return 0xff; } - PANIC("not impl"); + __unreachable(); } uint64 -FDCDevice::Read16(uint32 addr) +FDCDevice::Write(uint32 addr, uint32 data) { - return 0xff00 | Read8(addr + 1); -} + gMPU->AddCycle(19); // InsideOut p.135 -uint64 -FDCDevice::Write8(uint32 addr, uint32 data) -{ - uint32 offset = addr - baseaddr; - switch (offset) { - case 3: + switch (addr) { + case 0: + return 0; + + case 1: WriteCmd(data); return 0; - case 5: + + case 2: if ((data & 0x0f) != 0) { fdc.drivesel = data & 0x0f; putlog(1, "ドライブ選択%s%s%s%s", @@ -77,7 +81,7 @@ FDCDevice::Write8(uint32 addr, uint32 da } return 0; - case 7: + case 3: fdc.is2DD = ((data & 0x10) != 0); fdc.accdrive = data & 3; putlog(1, "アクセスドライブ %s #%d", @@ -90,23 +94,14 @@ FDCDevice::Write8(uint32 addr, uint32 da putlog(1, "ドライブ #%d モーターオフ", fdc.accdrive); } return 0; - - default: - break; } - PANIC("FDC 未実装書き込み $%06x <- $%02x", addr, data); - return 0; -} - -uint64 -FDCDevice::Write16(uint32 addr, uint32 data) -{ - return Write8(addr + 1, data); + __unreachable(); } uint64 -FDCDevice::Peek8(uint32 addr) +FDCDevice::Peek(uint32 addr) { + // XXX 未実装 return 0xff; } @@ -265,6 +260,11 @@ FDCDevice::exec_phase() case FDC::CMD_SENSE_INTERRUPT_STATUS: { putlog(1, "Exec フェーズ: SENSE INTERRUPT STATUS"); + // XXX とりあえずここで割り込みを下げる。 + // 実際には割り込み状態をラッチして信号線に出すというコマンドで + // 割り込み要因がオフになっていればそれによってネゲートされる + // ということのようだ。 + gPEDEC->NegateINT(this); // XXX まだフロッピー挿入はない uint8 st0 = 0; st0 |= FDC::ST0_IC_NT; @@ -317,9 +317,9 @@ FDCDevice::result_phase() // イベントコールバック void -FDCDevice::Callback(int arg) +FDCDevice::Callback(Event& ev) { - switch (arg) { + switch (ev.code) { case FDC::CMD_RECALIBRATE: fdd[fdc.accdrive].seek = false; fdc.DIO = DIOtoHost; @@ -332,7 +332,7 @@ FDCDevice::Callback(int arg) void FDCDevice::Interrupt() { - gIOCon->IntFDC(); + gPEDEC->AssertINT(this); } // コマンド名