Esempio n. 1
0
 public void Reset()
 {
     this._interruptMessage = 0xffff;
     this._deviceFlags = DeviceFlagBits.NONE;
     this._lastInterruptType = InterruptType.NONE;
     this._currentOperation = OperationType.None;
     this._currentSector = 0;
     this._sectorsRemaining = 0;
     this._currentHeadSector = 0;
     this._currentMemoryAddress = 0x0000;
 }
Esempio n. 2
0
        public void Interrupt(out int additionalCycles)
        {
            // default to 0 cycles
            additionalCycles = 0;

            var msg = (InterruptMessage)this._system.Cpu.Registers[0];
            var param = this._system.Cpu.Registers[1];
            switch (msg)
            {
                case InterruptMessage.QUERY_MEDIA_PRESENT:
                    this._system.Cpu.Registers[0] = (ushort)ErrorCode.ERROR_NONE;
                    this._system.Cpu.Registers[1] = this._currentDisk != null ? (ushort)1 : (ushort)0;
                    break;

                case InterruptMessage.QUERY_MEDIA_PARAMETERS:
                    if (this._currentDisk == null)
                    {
                        this._system.Cpu.Registers[0] = (ushort)ErrorCode.ERROR_NO_MEDIA;
                        break;
                    }
                    this._system.Cpu.Registers[0] = (ushort)ErrorCode.ERROR_NONE;
                    this._system.Cpu.Registers[1] = (ushort)this._currentDisk.WordsPerSector;
                    this._system.Cpu.Registers[2] = (ushort)this._currentDisk.NumSectors;
                    this._system.Cpu.Registers[3] = this._currentDisk.WriteLocked ? (ushort)1 : (ushort)0;
                    break;

                case InterruptMessage.QUERY_DEVICE_FLAGS:
                    this._system.Cpu.Registers[0] = (ushort)ErrorCode.ERROR_NONE;
                    this._system.Cpu.Registers[1] = (ushort)this._deviceFlags;
                    break;

                case InterruptMessage.UPDATE_DEVICE_FLAGS:
                    this._system.Cpu.Registers[0] = (ushort)ErrorCode.ERROR_NONE;
                    this._deviceFlags = (DeviceFlagBits)this._system.Cpu.Registers[1];
                    break;

                case InterruptMessage.QUERY_INTERRUPT_TYPE:
                    this._system.Cpu.Registers[0] = (ushort)ErrorCode.ERROR_NONE;
                    this._system.Cpu.Registers[1] = (ushort)this._lastInterruptType;
                    break;

                case InterruptMessage.SET_INTERRUPT_MESSAGE:
                    this._system.Cpu.Registers[0] = (ushort)ErrorCode.ERROR_NONE;
                    this._interruptMessage = this._system.Cpu.Registers[1];
                    break;

                case InterruptMessage.READ_SECTORS:
                    if (this._currentDisk == null)
                    {
                        this._system.Cpu.Registers[0] = (ushort)ErrorCode.ERROR_NO_MEDIA;
                        break;
                    }
                    if (this._currentOperation != OperationType.None)
                    {
                        this._system.Cpu.Registers[0] = (ushort)ErrorCode.ERROR_PENDING;
                        break;
                    }
                    if (param >= this._currentDisk.NumSectors || param + this._system.Cpu.Registers[2] > this._currentDisk.NumSectors)
                    {
                        this._system.Cpu.Registers[0] = (ushort)ErrorCode.ERROR_INVALID_SECTOR;
                        break;
                    }

                    this._currentOperation = OperationType.Read;
                    this._currentSector = param;
                    this._sectorsRemaining = this._system.Cpu.Registers[2];
                    this._currentMemoryAddress = this._system.Cpu.Registers[3];
                    if (!this.NonBlockingFlag) this._system.BlockExecution(true);
                    QueueNextStep();
                    this._system.Cpu.Registers[0] = (ushort)ErrorCode.ERROR_NONE;
                    break;

                case InterruptMessage.WRITE_SECTORS:
                    if (this._currentDisk == null)
                    {
                        this._system.Cpu.Registers[0] = (ushort)ErrorCode.ERROR_NO_MEDIA;
                        break;
                    }
                    if (this._currentOperation != OperationType.None)
                    {
                        this._system.Cpu.Registers[0] = (ushort)ErrorCode.ERROR_PENDING;
                        break;
                    }
                    if (param >= this._currentDisk.NumSectors || param + this._system.Cpu.Registers[2] > this._currentDisk.NumSectors)
                    {
                        this._system.Cpu.Registers[0] = (ushort)ErrorCode.ERROR_INVALID_SECTOR;
                        break;
                    }

                    this._currentOperation = OperationType.Write;
                    this._currentSector = param;
                    this._sectorsRemaining = this._system.Cpu.Registers[2];
                    this._currentMemoryAddress = this._system.Cpu.Registers[3];
                    if (!this.NonBlockingFlag) this._system.BlockExecution(true);
                    QueueNextStep();
                    this._system.Cpu.Registers[0] = (ushort)ErrorCode.ERROR_NONE;
                    break;

                case InterruptMessage.QUERY_MEDIA_QUALITY:
                    if (this._currentDisk == null)
                    {
                        this._system.Cpu.Registers[0] = (ushort)ErrorCode.ERROR_NO_MEDIA;
                        break;
                    }
                    this._system.Cpu.Registers[0] = (ushort)ErrorCode.ERROR_NONE;
                    this._system.Cpu.Registers[1] = (ushort)this._currentDisk.MediaType;
                    break;
            }
        }