1 #pragma once
2 #include "stdafx.h"
3 #include <assert.h>
4 #include "BaseMapper.h"
5 #include "CPU.h"
6 #include "EmulationSettings.h"
7 #include "FdsLoader.h"
8 #include "Console.h"
9 
10 class FdsAudio;
11 
12 class FDS : public BaseMapper
13 {
14 private:
15 	static constexpr uint32_t NoDiskInserted = 0xFF;
16 	bool _disableAutoInsertDisk;
17 
18 	unique_ptr<FdsAudio> _audio;
19 	EmulationSettings* _settings = nullptr;
20 
21 	//Write registers
22 	uint16_t _irqReloadValue = 0;
23 	uint16_t _irqCounter = 0;
24 	bool _irqEnabled = false;
25 	bool _irqRepeatEnabled = false;
26 
27 	bool _diskRegEnabled = true;
28 	bool _soundRegEnabled = true;
29 
30 	uint8_t _writeDataReg = 0;
31 
32 	bool _motorOn = false;
33 	bool _resetTransfer = false;
34 	bool _readMode = false;
35 	bool _crcControl = false;
36 	bool _diskReady = false;
37 	bool _diskIrqEnabled = false;
38 
39 	int32_t _autoDiskEjectCounter = -1;
40 	int32_t _autoDiskSwitchCounter = -1;
41 	int32_t _restartAutoInsertCounter = -1;
42 	uint32_t _previousFrame = 0;
43 	int32_t _lastDiskCheckFrame = 0;
44 	int32_t _successiveChecks = 0;
45 	uint32_t _previousDiskNumber = FDS::NoDiskInserted;
46 
47 	uint8_t _extConWriteReg = 0;
48 
49 	//Read registers
50 	bool _badCrc = false;
51 	bool _endOfHead = false;
52 	bool _readWriteEnabled = false;
53 
54 	uint8_t _readDataReg = 0;
55 
56 	bool _diskWriteProtected = false;
57 
58 	//Internal values
59 	uint32_t _diskNumber = FDS::NoDiskInserted;
60 	uint32_t _diskPosition = 0;
61 	uint32_t _delay = 0;
62 	uint16_t _crcAccumulator;
63 	bool _previousCrcControlFlag = false;
64 	bool _gapEnded = true;
65 	bool _scanningDisk = false;
66 	bool _transferComplete = false;
67 
68 	vector<uint8_t> _fdsRawData;
69 	vector<vector<uint8_t>> _fdsDiskSides;
70 	vector<vector<uint8_t>> _fdsDiskHeaders;
71 	string _romFilepath;
72 
73 	bool _gameStarted;
74 
75 protected:
GetPRGPageSize()76 	virtual uint16_t GetPRGPageSize() override { return 0x2000; }
GetCHRPageSize()77 	virtual uint16_t GetCHRPageSize() override { return 0x2000; }
GetWorkRamPageSize()78 	virtual uint32_t GetWorkRamPageSize() override { return 0x8000; }
GetWorkRamSize()79 	virtual uint32_t GetWorkRamSize() override { return 0x8000; }
RegisterStartAddress()80 	uint16_t RegisterStartAddress() override { return 0x4020; }
RegisterEndAddress()81 	uint16_t RegisterEndAddress() override { return 0x4092; }
AllowRegisterRead()82 	bool AllowRegisterRead() override { return true; }
83 
84 	void InitMapper() override;
85 	void InitMapper(RomData &romData) override;
86 	void LoadDiskData(vector<uint8_t> ipsData = vector<uint8_t>());
87 	vector<uint8_t> CreateIpsPatch();
88 	void Reset(bool softReset) override;
89 
90 	uint32_t GetFdsDiskSideSize(uint8_t side);
91 	uint8_t ReadFdsDisk();
92 	void WriteFdsDisk(uint8_t value);
93 
94 	void ProcessAutoDiskInsert();
95 
96 	void ClockIrq();
97 
98 	void ProcessCpuClock() override;
99 	void UpdateCrc(uint8_t value);
100 
101 	void WriteRegister(uint16_t addr, uint8_t value) override;
102 	uint8_t ReadRegister(uint16_t addr) override;
103 
104 	uint8_t ReadRAM(uint16_t addr) override;
105 
106 	void StreamState(bool saving) override;
107 
108 public:
109 	~FDS();
110 
111 	void SaveBattery() override;
112 	ConsoleFeatures GetAvailableFeatures() override;
113 
114 	uint32_t GetSideCount();
115 
116 	void EjectDisk();
117 	void InsertDisk(uint32_t diskNumber);
118 	uint32_t GetCurrentDisk();
119 	bool IsDiskInserted();
120 
121 	bool IsAutoInsertDiskEnabled();
122 };