|
|
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.9 root 14: #include "monitor.h"
1.1.1.11 root 15: #include <array>
16:
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: // 共通部分
48: int MonitorUpdateCommon(TextScreen& screen, int y);
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.10 root 83: // ADPCM のサンプリングレートの 2bit を取得する
84: uint8 GetADPCMRate() const { return adpcm_rate; }
85:
1.1 root 86: protected:
87: // BusIO インタフェース
88: static const uint32 NPORT = 4;
1.1.1.13! root 89: busdata ReadPort(uint32 offset);
! 90: busdata WritePort(uint32 offset, uint32 data);
! 91: busdata PeekPort(uint32 offset);
1.1.1.9 root 92:
93: private:
1.1.1.13! root 94: void SetPC(uint, uint) override;
1.1.1.10 root 95:
96: bool pan_left {};
97: bool pan_right {};
98: uint adpcm_rate {};
1.1 root 99: };
100:
1.1.1.7 root 101: class PIO0Device : public i8255Device
1.1 root 102: {
1.1.1.2 root 103: using inherited = i8255Device;
1.1.1.11 root 104:
105: static const int INT_H = 0;
106: static const int INT_L = 1;
107:
1.1 root 108: public:
109: PIO0Device();
1.1.1.12 root 110: ~PIO0Device() override;
1.1 root 111:
1.1.1.2 root 112: bool Init() override;
1.1.1.11 root 113: void ResetHard(bool poweron) override;
1.1.1.3 root 114:
1.1.1.9 root 115: // DIPSW #1-1 が Up なら true を返す (ROM エミュレーション用)
116: bool IsDIPSW11Up() const { return dipsw1[0]; }
1.1 root 117:
1.1.1.11 root 118: // XP からの割り込みは PIO0 が中継する
119: void InterruptXPHigh();
120: void InterruptXPLow();
121:
1.1 root 122: protected:
123: // BusIO インタフェース
124: static const uint32 NPORT = 4;
1.1.1.13! root 125: busdata ReadPort(uint32 offset);
! 126: busdata WritePort(uint32 offset, uint32 data);
! 127: busdata PeekPort(uint32 offset);
1.1 root 128:
129: private:
130: uint32 GetPA() const;
131: uint32 GetPB() const;
132: uint32 GetPC() const;
1.1.1.13! root 133: void SetPC(uint, uint) override;
1.1.1.11 root 134: void ChangeInterrupt();
1.1 root 135:
1.1.1.7 root 136: DECLARE_MONITOR_CALLBACK(MonitorUpdate);
137:
1.1 root 138: bool dipsw1[8] {};
139: bool dipsw2[8] {};
1.1.1.11 root 140: bool msb_first {}; // DIP-SW の1番が MSB なら true (LUNA-88K)
141: std::array<bool, 2> intreq {}; // XP 割り込み要求
142: std::array<bool, 2> inten {}; // XP 割り込み許可
1.1.1.4 root 143: bool parity {}; // $40 パリティ有効/無効
144: bool xp_reset {}; // $80 XP リセット
1.1.1.7 root 145:
146: Monitor monitor { this };
1.1.1.11 root 147:
148: InterruptDevice *interrupt {};
149: PIO1Device *pio1 {};
1.1 root 150: };
151:
1.1.1.7 root 152: class PIO1Device : public i8255Device
1.1 root 153: {
1.1.1.2 root 154: using inherited = i8255Device;
1.1 root 155: public:
156: PIO1Device();
1.1.1.12 root 157: ~PIO1Device() override;
1.1 root 158:
1.1.1.11 root 159: bool Init() override;
1.1.1.9 root 160: void ResetHard(bool poweron) override;
1.1.1.4 root 161:
1.1.1.11 root 162: // PIO0 の下請け
163: void MonitorUpdatePIO1(TextScreen& screen, int y);
164:
1.1 root 165: // BusIO インタフェース
1.1.1.13! root 166: // (内蔵 ROM からのアクセス用に特別に public にしてある)
! 167: busdata WritePort(uint32 offset, uint32 data);
! 168: protected:
1.1 root 169: static const uint32 NPORT = 4;
1.1.1.13! root 170: busdata ReadPort(uint32 offset);
! 171: busdata PeekPort(uint32 offset);
1.1 root 172:
173: private:
1.1.1.11 root 174: uint32 GetPC() const;
1.1.1.13! root 175: void SetPC(uint, uint) override;
1.1 root 176:
1.1.1.11 root 177: DECLARE_MONITOR_CALLBACK(MonitorUpdate);
178:
1.1.1.4 root 179: bool power {}; // パワーダウン (false で電源オフ指示)
180: bool xp_intreq {}; // XP 割り込み要求。あり(true)なら %0
1.1.1.11 root 181:
182: LCDDevice *lcd {};
183: MPU64180Device *mpu64180 {};
184: PowerDevice *powerdev {};
1.1 root 185: };
186:
1.1.1.11 root 187: static inline PPIDevice *GetPPIDevice() {
188: return Object::GetObject<PPIDevice>(OBJ_PPI);
189: }
190: static inline PIO0Device *GetPIO0Device() {
191: return Object::GetObject<PIO0Device>(OBJ_PIO0);
192: }
193: static inline PIO1Device *GetPIO1Device() {
194: return Object::GetObject<PIO1Device>(OBJ_PIO1);
195: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.