|
|
1.1 root 1: /* Previous - ramdac.c
2:
3: This file is distributed under the GNU Public License, version 2 or at
4: your option any later version. Read the file gpl.txt for details.
5:
6: Brooktree Bt463 RAMDAC emulation.
7:
8: This chip was is used in color NeXTstations and NeXTdimension.
9:
10: */
11:
12: #include "ioMem.h"
13: #include "ioMemTables.h"
14: #include "m68000.h"
15: #include "configuration.h"
16: #include "ramdac.h"
17: #include "sysReg.h"
18:
19: #define IO_SEG_MASK 0x1FFFF
20:
21: #define LOG_RAMDAC_LEVEL LOG_DEBUG
22:
23:
24: /* Bt 463 RAMDAC */
25:
26: #define BT_ADDR_MASK 0x0FFF
27: #define BT_ADDR_CCR 0x0100
28: #define BT_ADDR_REG 0x0200
29: #define BT_ADDR_WTT 0x0300
30:
31: #define BT463_ID 0x2A
32: #define BT463_REV 0x0A
33:
34: #define BT_REG_ID 0x0
35: #define BT_REG_CR0 0x1
36: #define BT_REG_CR1 0x2
37: #define BT_REG_CR2 0x3
38: #define BT_REG_RM0 0x5
39: #define BT_REG_RM1 0x6
40: #define BT_REG_RM2 0x7
41: #define BT_REG_RM3 0x8
42: #define BT_REG_BM0 0x9
43: #define BT_REG_BM1 0xa
44: #define BT_REG_BM2 0xb
45: #define BT_REG_BM3 0xc
46: #define BT_REG_TEST 0xd
47: #define BT_REG_ISR 0xe
48: #define BT_REG_OSR 0xf
49: #define BT_REG_REV 0x20
50:
51:
52:
53: static void bt463_autoinc(bt463* ramdac) {
54: ramdac->idx++;
55: if(ramdac->idx > 2) {
56: ramdac->idx = 0;
57: ramdac->addr++;
58: ramdac->addr &= 0x0FFF;
59: }
60: }
61:
62: static void bt463_autoinc_reg(bt463* ramdac) {
63: ramdac->idx = 0;
64: ramdac->addr++;
65: ramdac->addr &= 0x0FFF;
66: }
67:
68: /* BT463 Registers */
69: static uae_u32 bt463_read_reg(bt463* ramdac) {
70: uae_u32 result = 0;
71:
72: if ((ramdac->addr&0xFF)<0x10) {
73: switch (ramdac->addr&0x0F) {
74: case BT_REG_ID:
75: result = BT463_ID;
76: bt463_autoinc_reg(ramdac);
77: break;
78: case BT_REG_ISR:
79: case BT_REG_OSR:
80: result = ramdac->reg[(ramdac->addr&0x0F)*3+ramdac->idx];
81: bt463_autoinc(ramdac);
82: break;
83: default:
84: result = ramdac->reg[(ramdac->addr&0x0F)*3];
85: bt463_autoinc_reg(ramdac);
86: break;
87: }
88: } else if ((ramdac->addr&0xFF)==BT_REG_REV){
89: result = BT463_REV;
90: bt463_autoinc_reg(ramdac);
91: }
92:
93: return result;
94: }
95:
96: static void bt463_write_reg(bt463* ramdac, uae_u32 val) {
97:
98: if ((ramdac->addr&0xFF)<0x10) {
99: switch (ramdac->addr&0x0F) {
100: case BT_REG_ID:
101: bt463_autoinc_reg(ramdac);
102: break;
103: case BT_REG_ISR:
104: case BT_REG_OSR:
105: ramdac->reg[(ramdac->addr&0x0F)*3+ramdac->idx] = val & 0xFF;
106: bt463_autoinc(ramdac);
107: break;
108: default:
109: ramdac->reg[(ramdac->addr&0x0F)*3] = val & 0xFF;
110: bt463_autoinc_reg(ramdac);
111: break;
112: }
113: }
114: }
115:
116: /* BT463 Cursor Color */
117: static uae_u32 bt463_read_ccr(bt463* ramdac) {
118: uae_u32 result = 0;
119:
120: if ((ramdac->addr&0xFF)<2) {
121: result = ramdac->ccr[(ramdac->addr&1)*3+ramdac->idx];
122: bt463_autoinc(ramdac);
123: }
124:
125: return result;
126: }
127:
128: static void bt463_write_ccr(bt463* ramdac, uae_u32 val) {
129:
130: if ((ramdac->addr&0xFF)<4) {
131: ramdac->ccr[(ramdac->addr&3)*3+ramdac->idx] = val & 0xFF;
132: bt463_autoinc(ramdac);
133: }
134: }
135:
136: /* BT463 Window Type Table */
137: static uae_u32 bt463_read_wtt(bt463* ramdac) {
138: uae_u32 result = 0;
139:
140: if ((ramdac->addr&0xFF)<0x10) {
141: switch (ramdac->idx) {
142: case 0:
143: ramdac->wtt_tmp = ramdac->wtt[ramdac->addr&0x0F];
144: result = ramdac->wtt_tmp & 0xFF;
145: break;
146: case 1:
147: result = (ramdac->wtt_tmp >> 8) & 0xFF;
148: break;
149: case 2:
150: result = (ramdac->wtt_tmp >> 16) & 0xFF;
151: break;
152: default:
153: break;
154: }
155: bt463_autoinc(ramdac);
156: }
157:
158: return result;
159: }
160:
161: static void bt463_write_wtt(bt463* ramdac, uae_u32 val) {
162:
163: if ((ramdac->addr&0xFF)<0x10) {
164: switch (ramdac->idx) {
165: case 0:
166: ramdac->wtt_tmp = val & 0x0000FF;
167: break;
168: case 1:
169: ramdac->wtt_tmp |= (val << 8) & 0x00FF00;
170: break;
171: case 2:
172: ramdac->wtt_tmp |= (val << 16) & 0xFF0000;
173: ramdac->wtt[ramdac->addr&0x0F] = ramdac->wtt_tmp;
174: break;
175: default:
176: break;
177: }
178: bt463_autoinc(ramdac);
179: }
180: }
181:
182: /* BT463 Palette RAM */
183: static uae_u32 bt463_read_palette(bt463* ramdac) {
184: uae_u32 result = 0;
185:
186: if (ramdac->addr<0x210) {
187: result = ramdac->ram[ramdac->addr*3+ramdac->idx];
188: }
189: bt463_autoinc(ramdac);
190:
191: return result;
192: }
193:
194: static void bt463_write_palette(bt463* ramdac, uae_u32 val) {
195:
196: if (ramdac->addr<0x210) {
197: ramdac->ram[ramdac->addr*3+ramdac->idx] = val & 0xFF;
198: }
199: bt463_autoinc(ramdac);
200: }
201:
202:
203:
204: /* BT463 Host Interface */
205: uae_u32 bt463_bget(bt463* ramdac, uaecptr addr) {
206:
207: switch(addr & 0xF) {
208: case 0:
209: ramdac->idx = 0;
210: return ramdac->addr & 0xFF;
211: case 0x4:
212: ramdac->idx = 0;
213: return (ramdac->addr >> 8) & 0x0F;
214: case 0x8:
215: switch (ramdac->addr&0x0F00) {
216: case BT_ADDR_CCR:
217: return bt463_read_ccr(ramdac);
218: case BT_ADDR_REG:
219: return bt463_read_reg(ramdac);
220: case BT_ADDR_WTT:
221: return bt463_read_wtt(ramdac);
222:
223: default: break;
224: }
225: break;
226: case 0xC:
227: return bt463_read_palette(ramdac);
228: }
229: return 0;
230: }
231:
232: void bt463_bput(bt463* ramdac, uaecptr addr, uae_u32 b) {
233: switch(addr & 0xF) {
234: case 0x0:
235: ramdac->addr &= 0x0F00;
236: ramdac->addr |= b & 0xFF;
237: ramdac->idx = 0;
238: break;
239: case 0x4:
240: ramdac->addr &= 0x00FF;
241: ramdac->addr |= (b & 0x0F) << 8;
242: ramdac->idx = 0;
243: break;
244: case 0x8:
245: switch (ramdac->addr&0x0F00) {
246: case BT_ADDR_CCR:
247: bt463_write_ccr(ramdac, b);
248: break;
249: case BT_ADDR_REG:
250: bt463_write_reg(ramdac, b);
251: break;
252: case BT_ADDR_WTT:
253: bt463_write_wtt(ramdac, b);
254: break;
255:
256: default:
257: break;
258: }
259: break;
260: case 0xC:
261: bt463_write_palette(ramdac, b);
262: break;
263: }
264: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.