|
|
1.1 root 1: //
2: // nono
1.1.1.2 root 3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
1.1 root 5: //
6:
1.1.1.9 root 7: //
8: // PIO/PPI (i8255)
9: //
10:
1.1 root 11: #pragma once
12:
1.1.1.10 root 13: #include "device.h"
1.1.1.11 root 14: #include <array>
15:
1.1.1.15 root 16: class ADPCMDevice;
1.1.1.11 root 17: class InterruptDevice;
18: class LCDDevice;
19: class MPU64180Device;
20: class PIO1Device;
21: class PowerDevice;
1.1 root 22:
23: // Intel 82C55 の仕様書にはコントロールポートからの読み出しは明記してある。
24: // NEC uPD8255 の仕様書にはコントロールポートからの読み出しについての記載が
25: // ない (禁止とも書いてない)。
1.1.1.7 root 26: class i8255Device : public IODevice
1.1 root 27: {
1.1.1.2 root 28: using inherited = IODevice;
1.1 root 29:
30: public:
1.1.1.13 root 31: explicit i8255Device(uint objid_);
1.1.1.12 root 32: ~i8255Device() override;
1.1 root 33:
1.1.1.9 root 34: void ResetHard(bool poweron) override;
1.1.1.4 root 35:
1.1 root 36: protected:
1.1.1.13 root 37: // BusIO インタフェース
38: bool PokePort(uint32 offset, uint32 data);
39:
1.1 root 40: // コントロールポートの読み出し
41: uint32 ReadCtrl() const { return ctrl; }
42: // コントロールポートへの書き込み
43: void WriteCtrl(uint32);
44: // PortC への個別書き込み
1.1.1.13 root 45: virtual void SetPC(uint, uint) = 0;
1.1 root 46:
1.1.1.11 root 47: // 共通部分
1.1.1.16! root 48: int MonitorScreenCommon(TextScreen& screen, int y);
1.1.1.11 root 49:
1.1 root 50: // 7 6 5 4 3 2 1 0
51: // 1 AM AM AD CHD BM BD CLD
52: // | | | | | | +--- ポートC下位グループの方向。入力なら1
53: // | | | | | +------ ポートB の方向。入力なら1
54: // | | | | +--------- ポートB のモード。
55: // | | | +------------- ポートC上位グループの方向。入力なら1
56: // | | +---------------- ポートA の方向。入力なら1
57: // +--+------------------- ポートA のモード。
58: uint8 ctrl = 0; // コントロールポートの値
59:
60: static const uint DIR_IN = 1;
61: static const uint DIR_OUT = 0;
62: // グループA/B (ポートA/B) のモード
63: uint GetGroupAMode() const { return (ctrl >> 5) & 3; }
64: uint GetGroupBMode() const { return (ctrl >> 2) & 1; }
65: // ポート A/B/C上位/C下位 の入出力方向
66: uint PortADir() const { return (ctrl & 0x10) ? DIR_IN : DIR_OUT; }
67: uint PortBDir() const { return (ctrl & 0x02) ? DIR_IN : DIR_OUT; }
68: uint PortCHDir() const { return (ctrl & 0x08) ? DIR_IN : DIR_OUT; }
69: uint PortCLDir() const { return (ctrl & 0x01) ? DIR_IN : DIR_OUT; }
70: };
71:
72:
1.1.1.7 root 73: class PPIDevice : public i8255Device
1.1 root 74: {
1.1.1.2 root 75: using inherited = i8255Device;
1.1.1.9 root 76:
1.1.1.13 root 77: static const uint32 baseaddr = 0xe9a000;
1.1 root 78:
79: public:
80: PPIDevice();
1.1.1.12 root 81: ~PPIDevice() override;
1.1 root 82:
1.1.1.15 root 83: bool Init() override;
1.1.1.10 root 84:
1.1 root 85: protected:
86: // BusIO インタフェース
87: static const uint32 NPORT = 4;
1.1.1.13 root 88: busdata ReadPort(uint32 offset);
89: busdata WritePort(uint32 offset, uint32 data);
90: busdata PeekPort(uint32 offset);
1.1.1.9 root 91:
92: private:
1.1.1.15 root 93: uint32 GetPC() const;
1.1.1.13 root 94: void SetPC(uint, uint) override;
1.1.1.10 root 95:
1.1.1.15 root 96: // ADPCM サンプリングレートの設定値(0..3)をこちらでも持っておく。
97: uint32 adpcm_rate {};
98:
99: ADPCMDevice *adpcm {};
1.1 root 100: };
101:
1.1.1.7 root 102: class PIO0Device : public i8255Device
1.1 root 103: {
1.1.1.2 root 104: using inherited = i8255Device;
1.1.1.11 root 105:
106: static const int INT_H = 0;
107: static const int INT_L = 1;
108:
1.1 root 109: public:
110: PIO0Device();
1.1.1.12 root 111: ~PIO0Device() override;
1.1 root 112:
1.1.1.2 root 113: bool Init() override;
1.1.1.11 root 114: void ResetHard(bool poweron) override;
1.1.1.3 root 115:
1.1.1.9 root 116: // DIPSW #1-1 が Up なら true を返す (ROM エミュレーション用)
117: bool IsDIPSW11Up() const { return dipsw1[0]; }
1.1 root 118:
1.1.1.11 root 119: // XP からの割り込みは PIO0 が中継する
120: void InterruptXPHigh();
121: void InterruptXPLow();
122:
1.1 root 123: protected:
124: // BusIO インタフェース
125: static const uint32 NPORT = 4;
1.1.1.13 root 126: busdata ReadPort(uint32 offset);
127: busdata WritePort(uint32 offset, uint32 data);
128: busdata PeekPort(uint32 offset);
1.1 root 129:
130: private:
131: uint32 GetPA() const;
132: uint32 GetPB() const;
133: uint32 GetPC() const;
1.1.1.13 root 134: void SetPC(uint, uint) override;
1.1.1.11 root 135: void ChangeInterrupt();
1.1 root 136:
1.1.1.16! root 137: DECLARE_MONITOR_SCREEN(MonitorScreen);
1.1.1.7 root 138:
1.1 root 139: bool dipsw1[8] {};
140: bool dipsw2[8] {};
1.1.1.11 root 141: bool msb_first {}; // DIP-SW の1番が MSB なら true (LUNA-88K)
142: std::array<bool, 2> intreq {}; // XP 割り込み要求
143: std::array<bool, 2> inten {}; // XP 割り込み許可
1.1.1.4 root 144: bool parity {}; // $40 パリティ有効/無効
145: bool xp_reset {}; // $80 XP リセット
1.1.1.7 root 146:
1.1.1.14 root 147: Monitor *monitor {};
1.1.1.11 root 148:
149: InterruptDevice *interrupt {};
150: PIO1Device *pio1 {};
1.1 root 151: };
152:
1.1.1.7 root 153: class PIO1Device : public i8255Device
1.1 root 154: {
1.1.1.2 root 155: using inherited = i8255Device;
1.1 root 156: public:
157: PIO1Device();
1.1.1.12 root 158: ~PIO1Device() override;
1.1 root 159:
1.1.1.11 root 160: bool Init() override;
1.1.1.9 root 161: void ResetHard(bool poweron) override;
1.1.1.4 root 162:
1.1.1.11 root 163: // PIO0 の下請け
1.1.1.16! root 164: void MonitorScreenPIO1(TextScreen& screen, int y);
1.1.1.11 root 165:
1.1 root 166: // BusIO インタフェース
1.1.1.13 root 167: // (内蔵 ROM からのアクセス用に特別に public にしてある)
168: busdata WritePort(uint32 offset, uint32 data);
169: protected:
1.1 root 170: static const uint32 NPORT = 4;
1.1.1.13 root 171: busdata ReadPort(uint32 offset);
172: busdata PeekPort(uint32 offset);
1.1 root 173:
174: private:
1.1.1.11 root 175: uint32 GetPC() const;
1.1.1.13 root 176: void SetPC(uint, uint) override;
1.1 root 177:
1.1.1.16! root 178: DECLARE_MONITOR_SCREEN(MonitorScreen);
1.1.1.11 root 179:
1.1.1.4 root 180: bool power {}; // パワーダウン (false で電源オフ指示)
181: bool xp_intreq {}; // XP 割り込み要求。あり(true)なら %0
1.1.1.11 root 182:
183: LCDDevice *lcd {};
184: MPU64180Device *mpu64180 {};
185: PowerDevice *powerdev {};
1.1 root 186: };
187:
1.1.1.16! root 188: inline PPIDevice *GetPPIDevice() {
1.1.1.11 root 189: return Object::GetObject<PPIDevice>(OBJ_PPI);
190: }
1.1.1.16! root 191: inline PIO0Device *GetPIO0Device() {
1.1.1.11 root 192: return Object::GetObject<PIO0Device>(OBJ_PIO0);
193: }
1.1.1.16! root 194: inline PIO1Device *GetPIO1Device() {
1.1.1.11 root 195: return Object::GetObject<PIO1Device>(OBJ_PIO1);
196: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.