|
|
1.1 root 1: //
2: // nono
1.1.1.3 ! root 3: // Copyright (C) 2020 nono project
! 4: // Licensed under nono-license.txt
1.1 root 5: //
6:
7: #include "lcd.h"
8:
1.1.1.2 root 9: std::unique_ptr<LCDDevice> gLCD;
1.1 root 10:
11: LCDDevice::LCDDevice()
12: {
13: logname = "lcd";
14: devname = "LCD(HD44780)";
15: monitor.Init(16, 2);
16: }
17:
18: LCDDevice::~LCDDevice()
19: {
20: }
21:
22: bool
23: LCDDevice::PowerOff()
24: {
25: // オフをどう表現するかはあるが、とりあえずモニタ画面での表示を消すのが
26: // 主目的なので空白で埋める。
27: memset(ddram, 0x20, sizeof(ddram));
28: return true;
29: }
30:
31: void
32: LCDDevice::SetRW(bool val)
33: {
34: rw = val;
35: putlog(2, "R/W = %c", val ? 'R' : 'W');
36: }
37:
38: void
39: LCDDevice::SetRS(int val)
40: {
41: rs = val;
42: putlog(2, "RS = %d", rs);
43: }
44:
45: void
46: LCDDevice::SetE(bool val)
47: {
48: en = val;
49: putlog(2, "E = %d", en);
50: }
51:
52: // E, RS, R/W 線の状態を取得する (PIO1 のポートC 読み込み用)
53: uint8
54: LCDDevice::Get() const
55: {
56: return (en ? 0x80 : 0)
57: | (rs >> 6)
58: | (rw ? 0x20 : 0);
59: }
60:
61: uint8
62: LCDDevice::Read()
63: {
64: if (en == false || rw == false) {
65: // XXX どうなるんだろ
66: return 0xff;
67: }
68: if (rs == 0) {
69: // ステータスレジスタの読み込み
70: // B A A A A A A A
71: // | +-+-+-+-+-+-+-- アドレスカウンタ
72: // +---------------- ビジーフラグ %1=BUSY
73:
74: // XXX ビジーは未実装
75: return addr;
76: } else {
77: putlog(0, "未実装データ読み込み");
78: }
79: return 0xff;
80: }
81:
82: void
83: LCDDevice::Write(uint8 data)
84: {
85: if (en == false || rw == true) {
86: // どうなるんだろ
87: return;
88: }
89: if (rs == 0) {
90: // コマンド書き込み
91: if ((data & 0x80)) {
92: addr = data & 0x7f;
93: putlog(1, "DDRAM アドレスセット $%02x", addr);
94: } else if ((data & 0x40)) {
95: putlog(0, "コマンド書き込み $%02x CGRAM アドレスセット(未実装)",
96: data);
97: } else if ((data & 0x20)) {
98: // ファンクション・セット
99: // 0x38 (8ビットバス、2行表示、8ライン/行)モードのみサポート
100: if (data != 0x38) {
101: putlog(0, "コマンド書き込み $%02x ファンクションセット(未実装)",
102: data);
103: }
104: } else if ((data & 0x10)) {
105: // カーソル移動
106: putlog(0, "コマンド書き込み $%02x カーソル移動(未実装)", data);
107: } else if ((data & 0x08)) {
108: // 表示ON/OFF
109: // 文字表示 ON/OFF のみサポート
110: disp_char = (data & 0x04);
111: // XXX それ以外は未サポート
112: } else if ((data & 0x04)) {
113: // エントリモード
114: addr_inc = (data & 0x02);
115: // XXX 表示シフトは未サポート
116: } else if ((data & 0x02)) {
117: // カーソルホーム
118: addr = 0;
119: } else if ((data & 0x01)) {
120: // 表示クリア
121: memset(ddram, 0x20, sizeof(ddram));
122: addr = 0;
123: } else {
124: // $00 が書き込まれるんだけど、データシートにはないんだよね。
125: // 無視していいかな。
126: putlog(2, "未定義書き込み $%02x", data);
127: }
128: } else {
129: putlog(1, "データ書き込み $%02x (x=%2d,y=%d)", data,
130: (addr & 0x3f), (addr / 0x40));
131: ddram[addr] = data;
132: // アドレス更新
133: // 1行0x40バイト分あるが実際には0x27までしか存在していない
134: if (addr_inc) {
135: addr++;
136: if (addr == 0x28)
137: addr = 0x40;
138: if (addr == 0x68)
139: addr = 0;
140: } else {
141: addr--;
142: if (addr == -1)
143: addr = 0x67;
144: if (addr == 0x3f)
145: addr = 0x27;
146: }
147: }
148: }
149:
1.1.1.2 root 150: // PIO1 からのピーク用
151: uint8
152: LCDDevice::Peek() const
153: {
154: if (en == false || rw == false) {
155: // XXX どうなるんだろ
156: return 0xff;
157: }
158: if (rs == 0) {
159: return addr;
160: } else {
161: // データ読み込みは未実装
162: }
163: return 0xff;
164: }
165:
1.1 root 166: bool
167: LCDDevice::MonitorUpdate()
168: {
169: char buf[17];
170:
171: monitor.Clear();
172:
173: for (int y = 0; y < 2; y++) {
174: memcpy(buf, &ddram[y * 0x40], 16);
175: buf[16] = '\0';
176: monitor.Print(0, y, "%s", buf);
177: }
178: return true;
179: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.