1
0
mirror of https://github.com/livingcomputermuseum/ContrAlto.git synced 2026-01-26 04:01:07 +00:00
Files
livingcomputermuseum.ContrAlto/Contralto/CPU/Tasks/DiskTask.cs

109 lines
3.9 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Contralto.Memory;
namespace Contralto.CPU
{
public partial class AltoCPU
{
/// <summary>
/// DiskTask provides implementation for disk-specific special functions
/// (for both Disk Sector and Disk Word tasks, since the special functions are
/// identical between the two)
/// </summary>
private class DiskTask : Task
{
public DiskTask(AltoCPU cpu, bool diskSectorTask) : base(cpu)
{
_taskType = diskSectorTask ? TaskType.DiskSector : TaskType.DiskWord;
_wakeup = false;
}
protected override ushort GetBusSource(int bs)
{
DiskBusSource dbs = (DiskBusSource)bs;
switch (dbs)
{
case DiskBusSource.ReadKSTAT:
return _cpu._system.DiskController.KSTAT;
case DiskBusSource.ReadKDATA:
return _cpu._system.DiskController.KDATA;
default:
throw new InvalidOperationException(String.Format("Unhandled bus source {0}", bs));
}
}
protected override void ExecuteSpecialFunction1(int f1)
{
DiskF1 df1 = (DiskF1)f1;
switch (df1)
{
case DiskF1.LoadKDATA:
// "The KDATA register is loaded from BUS[0-15]."
_cpu._system.DiskController.KDATA = _busData;
break;
case DiskF1.LoadKADR:
// "This causes the KADR register to be loaded from BUS[8-14].
// in addition, it causes the head address bit to be loaded from KDATA[13]."
// (the latter is done by DiskController)
_cpu._system.DiskController.KADR = (ushort)((_busData & 0xfe) >> 1);
break;
case DiskF1.LoadKCOMM:
_cpu._system.DiskController.KCOM = (ushort)((_busData & 0x7c00) >> 10);
break;
case DiskF1.CLRSTAT:
_cpu._system.DiskController.ClearStatus();
break;
case DiskF1.INCRECNO:
_cpu._system.DiskController.IncrementRecord();
break;
case DiskF1.LoadKSTAT:
// "KSTAT[12-15] are loaded from BUS[12-15]. (Actually BUS[13] is ORed onto
// KSTAT[13].)"
// OR in BUS[12-15] after masking in KSTAT[13] so it is ORed in properly.
_cpu._system.DiskController.KSTAT = (ushort)(((_cpu._system.DiskController.KSTAT & 0xfff4)) | (_busData & 0xf));
break;
case DiskF1.STROBE:
_cpu._system.DiskController.Strobe();
break;
default:
throw new InvalidOperationException(String.Format("Unhandled disk special function 1 {0}", df1));
}
}
protected override void ExecuteSpecialFunction2(int f2)
{
DiskF2 df2 = (DiskF2)f2;
switch (df2)
{
case DiskF2.INIT:
// "NEXT<-NEXT OR (if WDTASKACT AND WDINIT) then 37B else 0
// TODO: figure out how WDTASKACT and WDINIT work.
throw new NotImplementedException("INIT not implemented.");
default:
throw new InvalidOperationException(String.Format("Unhandled disk special function 2 {0}", df2));
}
}
}
}
}