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