|
|
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.11! root 31: i8255Device(int objid_);
1.1.1.5 root 32: virtual ~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:
37: // コントロールポートの読み出し
38: uint32 ReadCtrl() const { return ctrl; }
39: // コントロールポートへの書き込み
40: void WriteCtrl(uint32);
41: // PortC への個別書き込み
1.1.1.9 root 42: virtual void SetPC(int, int) = 0;
1.1 root 43:
1.1.1.11! root 44: // 共通部分
! 45: int MonitorUpdateCommon(TextScreen& screen, int y);
! 46:
1.1 root 47: // 7 6 5 4 3 2 1 0
48: // 1 AM AM AD CHD BM BD CLD
49: // | | | | | | +--- ポートC下位グループの方向。入力なら1
50: // | | | | | +------ ポートB の方向。入力なら1
51: // | | | | +--------- ポートB のモード。
52: // | | | +------------- ポートC上位グループの方向。入力なら1
53: // | | +---------------- ポートA の方向。入力なら1
54: // +--+------------------- ポートA のモード。
55: uint8 ctrl = 0; // コントロールポートの値
56:
57: static const uint DIR_IN = 1;
58: static const uint DIR_OUT = 0;
59: // グループA/B (ポートA/B) のモード
60: uint GetGroupAMode() const { return (ctrl >> 5) & 3; }
61: uint GetGroupBMode() const { return (ctrl >> 2) & 1; }
62: // ポート A/B/C上位/C下位 の入出力方向
63: uint PortADir() const { return (ctrl & 0x10) ? DIR_IN : DIR_OUT; }
64: uint PortBDir() const { return (ctrl & 0x02) ? DIR_IN : DIR_OUT; }
65: uint PortCHDir() const { return (ctrl & 0x08) ? DIR_IN : DIR_OUT; }
66: uint PortCLDir() const { return (ctrl & 0x01) ? DIR_IN : DIR_OUT; }
67: };
68:
69:
1.1.1.7 root 70: class PPIDevice : public i8255Device
1.1 root 71: {
1.1.1.2 root 72: using inherited = i8255Device;
1.1.1.9 root 73:
1.1 root 74: static const int baseaddr = 0xe9a000;
75:
76: public:
77: PPIDevice();
1.1.1.5 root 78: virtual ~PPIDevice() override;
1.1 root 79:
1.1.1.10 root 80: // ADPCM のサンプリングレートの 2bit を取得する
81: uint8 GetADPCMRate() const { return adpcm_rate; }
82:
1.1 root 83: protected:
84: // BusIO インタフェース
85: static const uint32 NPORT = 4;
1.1.1.6 root 86: uint64 Read(uint32 offset);
87: uint64 Write(uint32 offset, uint32 data);
88: uint64 Peek(uint32 offset);
1.1.1.9 root 89:
90: private:
91: void SetPC(int, int) override;
1.1.1.10 root 92:
93: bool pan_left {};
94: bool pan_right {};
95: uint adpcm_rate {};
1.1 root 96: };
97:
1.1.1.7 root 98: class PIO0Device : public i8255Device
1.1 root 99: {
1.1.1.2 root 100: using inherited = i8255Device;
1.1.1.11! root 101:
! 102: static const int INT_H = 0;
! 103: static const int INT_L = 1;
! 104:
1.1 root 105: public:
106: PIO0Device();
1.1.1.5 root 107: virtual ~PIO0Device() override;
1.1 root 108:
1.1.1.2 root 109: bool Init() override;
1.1.1.11! root 110: void ResetHard(bool poweron) override;
1.1.1.3 root 111:
1.1.1.9 root 112: // DIPSW #1-1 が Up なら true を返す (ROM エミュレーション用)
113: bool IsDIPSW11Up() const { return dipsw1[0]; }
1.1 root 114:
1.1.1.11! root 115: // XP からの割り込みは PIO0 が中継する
! 116: void InterruptXPHigh();
! 117: void InterruptXPLow();
! 118:
1.1 root 119: protected:
120: // BusIO インタフェース
121: static const uint32 NPORT = 4;
1.1.1.6 root 122: uint64 Read(uint32 offset);
123: uint64 Write(uint32 offset, uint32 data);
124: uint64 Peek(uint32 offset);
1.1 root 125:
126: private:
127: uint32 GetPA() const;
128: uint32 GetPB() const;
129: uint32 GetPC() const;
1.1.1.2 root 130: void SetPC(int, int) override;
1.1.1.11! root 131: void ChangeInterrupt();
1.1 root 132:
1.1.1.7 root 133: DECLARE_MONITOR_CALLBACK(MonitorUpdate);
134:
1.1 root 135: bool dipsw1[8] {};
136: bool dipsw2[8] {};
1.1.1.11! root 137: bool msb_first {}; // DIP-SW の1番が MSB なら true (LUNA-88K)
! 138: std::array<bool, 2> intreq {}; // XP 割り込み要求
! 139: std::array<bool, 2> inten {}; // XP 割り込み許可
1.1.1.4 root 140: bool parity {}; // $40 パリティ有効/無効
141: bool xp_reset {}; // $80 XP リセット
1.1.1.7 root 142:
143: Monitor monitor { this };
1.1.1.11! root 144:
! 145: InterruptDevice *interrupt {};
! 146: PIO1Device *pio1 {};
1.1 root 147: };
148:
1.1.1.7 root 149: class PIO1Device : public i8255Device
1.1 root 150: {
1.1.1.2 root 151: using inherited = i8255Device;
1.1 root 152: public:
153: PIO1Device();
1.1.1.5 root 154: virtual ~PIO1Device() override;
1.1 root 155:
1.1.1.11! root 156: bool Init() override;
1.1.1.9 root 157: void ResetHard(bool poweron) override;
1.1.1.4 root 158:
1.1.1.11! root 159: // BusIO インタフェース
! 160: // (内蔵 ROM からのアクセス用に特別に public にしてある)
! 161: uint64 Write(uint32 offset, uint32 data);
! 162:
! 163: // PIO0 の下請け
! 164: void MonitorUpdatePIO1(TextScreen& screen, int y);
! 165:
1.1 root 166: protected:
167: // BusIO インタフェース
168: static const uint32 NPORT = 4;
1.1.1.6 root 169: uint64 Read(uint32 offset);
170: uint64 Peek(uint32 offset);
1.1 root 171:
172: private:
1.1.1.11! root 173: uint32 GetPC() const;
1.1.1.2 root 174: void SetPC(int, int) 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.