|
|
1.1 root 1: #include "main.h"
2: #include "configuration.h"
3: #include "m68000.h"
4: #include "sysdeps.h"
5: #include "nbic.h"
6:
7: #define LOG_NEXTBUS_LEVEL LOG_NONE
8:
9: /* NeXTbus and NeXTbus Interface Chip emulation */
10:
11: /* NBIC Registers */
12:
13: struct {
14: Uint32 control;
15: Uint32 id;
16: Uint8 intstatus;
17: Uint8 intmask;
18: } nbic;
19:
20:
21: /* Control: 0x02020000 (rw), only non-Turbo */
22: #define NBIC_CTRL_IGNSID0 0x10000000 /* Ignore slot ID bit 0 */
23: #define NBIC_CTRL_STFWD 0x08000000 /* Store forward */
24: #define NBIC_CTRL_RMCOL 0x04000000 /* Read modify cycle collision */
25:
26: /* ID: 0x02020004 (w), 0xF0FFFFFx (r), only non-Turbo */
27: #define NBIC_ID_VALID 0x80000000
28: #define NBIC_ID_M_MASK 0x7FFF0000 /* Manufacturer ID */
29: #define NBIC_ID_B_MASK 0x0000FFFF /* Board ID */
30:
31: /* Interrupt: 0xF0FFFFE8 (r) */
32: #define NBIC_INT_STATUS 0x80
33:
34: /* Interrupt mask: 0xF0FFFFEC (rw) */
35: #define NBIC_INT_MASK 0x80
36:
37:
38: /* Register access functions */
39: static Uint8 nbic_control_read0(Uint32 addr) {
40: Log_Printf(LOG_WARN, "[NBIC] Control (byte 0) read at %08X",addr);
41: return (nbic.control>>24);
42: }
43: static Uint8 nbic_control_read1(Uint32 addr) {
44: Log_Printf(LOG_WARN, "[NBIC] Control (byte 1) read at %08X",addr);
45: return (nbic.control>>16);
46: }
47: static Uint8 nbic_control_read2(Uint32 addr) {
48: Log_Printf(LOG_WARN, "[NBIC] Control (byte 2) read at %08X",addr);
49: return (nbic.control>>8);
50: }
51: static Uint8 nbic_control_read3(Uint32 addr) {
52: Log_Printf(LOG_WARN, "[NBIC] Control (byte 3) read at %08X",addr);
53: return nbic.control;
54: }
55:
56: static void nbic_control_write0(Uint32 addr, Uint8 val) {
57: Log_Printf(LOG_WARN, "[NBIC] Control (byte 0) write %02X at %08X",val,addr);
58: nbic.control &= 0x00FFFFFF;
59: nbic.control |= (val&0xFF)<<24;
60: }
61: static void nbic_control_write1(Uint32 addr, Uint8 val) {
62: Log_Printf(LOG_WARN, "[NBIC] Control (byte 1) write %02X at %08X",val,addr);
63: nbic.control &= 0xFF00FFFF;
64: nbic.control |= (val&0xFF)<<16;
65: }
66: static void nbic_control_write2(Uint32 addr, Uint8 val) {
67: Log_Printf(LOG_WARN, "[NBIC] Control (byte 2) write %02X at %08X",val,addr);
68: nbic.control &= 0xFFFF00FF;
69: nbic.control |= (val&0xFF)<<8;
70: }
71: static void nbic_control_write3(Uint32 addr, Uint8 val) {
72: Log_Printf(LOG_WARN, "[NBIC] Control (byte 3) write %02X at %08X",val,addr);
73: nbic.control &= 0xFFFFFF00;
74: nbic.control |= val&0xFF;
75: }
76:
77:
78: static Uint8 nbic_id_read0(Uint32 addr) {
79: Log_Printf(LOG_WARN, "[NBIC] ID (byte 0) read at %08X",addr);
80: return (nbic.id>>24);
81: }
82: static Uint8 nbic_id_read1(Uint32 addr) {
83: Log_Printf(LOG_WARN, "[NBIC] ID (byte 1) read at %08X",addr);
84: return (nbic.id>>16);
85: }
86: static Uint8 nbic_id_read2(Uint32 addr) {
87: Log_Printf(LOG_WARN, "[NBIC] ID (byte 2) read at %08X",addr);
88: return (nbic.id>>8);
89: }
90: static Uint8 nbic_id_read3(Uint32 addr) {
91: Log_Printf(LOG_WARN, "[NBIC] ID (byte 3) read at %08X",addr);
92: return nbic.id;
93: }
94:
95: static void nbic_id_write0(Uint32 addr, Uint8 val) {
96: Log_Printf(LOG_WARN, "[NBIC] ID (byte 0) write %02X at %08X",val,addr);
97: nbic.id &= 0x00FFFFFF;
98: nbic.id |= (val&0xFF)<<24;
99: }
100: static void nbic_id_write1(Uint32 addr, Uint8 val) {
101: Log_Printf(LOG_WARN, "[NBIC] ID (byte 1) write %02X at %08X",val,addr);
102: nbic.id &= 0xFF00FFFF;
103: nbic.id |= (val&0xFF)<<16;
104: }
105: static void nbic_id_write2(Uint32 addr, Uint8 val) {
106: Log_Printf(LOG_WARN, "[NBIC] ID (byte 2) write %02X at %08X",val,addr);
107: nbic.id &= 0xFFFF00FF;
108: nbic.id |= (val&0xFF)<<8;
109: }
110: static void nbic_id_write3(Uint32 addr, Uint8 val) {
111: Log_Printf(LOG_WARN, "[NBIC] ID (byte 3) write %02X at %08X",val,addr);
112: nbic.id &= 0xFFFFFF00;
113: nbic.id |= val&0xFF;
114: }
115:
116: static Uint8 nbic_intstatus_read(Uint32 addr) {
117: Log_Printf(LOG_WARN, "[NBIC] Interrupt status read at %08X",addr);
118: return nbic.intstatus;
119: }
120:
121: static Uint8 nbic_intmask_read(Uint32 addr) {
122: Log_Printf(LOG_WARN, "[NBIC] Interrupt mask read at %08X",addr);
123: return nbic.intmask;
124: }
125: static void nbic_intmask_write(Uint32 addr, Uint8 val) {
126: Log_Printf(LOG_WARN, "[NBIC] Interrupt mask write %02X at %08X",val,addr);
127: nbic.intmask = val;
128: }
129:
130: static Uint8 nbic_zero_read(Uint32 addr) {
131: Log_Printf(LOG_WARN, "[NBIC] zero read at %08X",addr);
132: return 0;
133: }
134: static void nbic_zero_write(Uint32 addr, Uint8 val) {
135: Log_Printf(LOG_WARN, "[NBIC] zero write %02X at %08X",val,addr);
136: }
137:
138: static Uint8 nbic_bus_error_read(Uint32 addr) {
139: Log_Printf(LOG_WARN, "[NBIC] bus error read at %08X",addr);
140: M68000_BusError(addr, 1);
141: return 0;
142: }
143: static void nbic_bus_error_write(Uint32 addr, Uint8 val) {
144: Log_Printf(LOG_WARN, "[NBIC] bus error write at %08X",addr);
145: M68000_BusError(addr, 0);
146: }
147:
148:
149: /* Direct register access */
150: static Uint8 (*nbic_read_reg[8])(Uint32) = {
151: nbic_control_read0, nbic_control_read1, nbic_control_read2, nbic_control_read3,
152: nbic_bus_error_read, nbic_bus_error_read, nbic_bus_error_read, nbic_bus_error_read
153: };
154:
155: static void (*nbic_write_reg[8])(Uint32, Uint8) = {
156: nbic_control_write0, nbic_control_write1, nbic_control_write2, nbic_control_write3,
157: nbic_id_write0, nbic_id_write1, nbic_id_write2, nbic_id_write3
158: };
159:
160:
161: Uint32 nbic_reg_lget(Uint32 addr) {
162: Uint32 val = 0;
163:
164: if (addr&3) {
165: Log_Printf(LOG_WARN, "[NBIC] Unaligned access at %08X.",addr);
166: abort();
167: }
168:
169: if ((addr&0x0000FFFF)>7) {
170: nbic_bus_error_read(addr);
171: } else {
172: val = nbic_read_reg[addr&7](addr)<<24;
173: val |= nbic_read_reg[(addr&7)+1](addr+1)<<16;
174: val |= nbic_read_reg[(addr&7)+2](addr+2)<<8;
175: val |= nbic_read_reg[(addr&7)+3](addr+3);
176: }
177:
178: return val;
179: }
180:
181: Uint32 nbic_reg_wget(uaecptr addr) {
182: Uint32 val = 0;
183:
184: if (addr&1) {
185: Log_Printf(LOG_WARN, "[NBIC] Unaligned access at %08X.",addr);
186: abort();
187: }
188:
189: if ((addr&0x0000FFFF)>7) {
190: nbic_bus_error_read(addr);
191: } else {
192: val = nbic_read_reg[addr&7](addr)<<8;
193: val |= nbic_read_reg[(addr&7)+1](addr);
194: }
195:
196: return val;
197: }
198:
199: Uint32 nbic_reg_bget(uaecptr addr) {
200: if ((addr&0x0000FFFF)>7) {
201: return nbic_bus_error_read(addr);
202: } else {
203: return nbic_read_reg[addr&7](addr);
204: }
205: }
206:
207: void nbic_reg_lput(uaecptr addr, Uint32 l) {
208: if (addr&3) {
209: Log_Printf(LOG_WARN, "[NBIC] Unaligned access at %08X.",addr);
210: abort();
211: }
212:
213: if ((addr&0x0000FFFF)>7) {
214: nbic_bus_error_write(addr,0);
215: } else {
216: nbic_write_reg[addr&7](addr,l>>24);
217: nbic_write_reg[(addr&7)+1](addr,l>>16);
218: nbic_write_reg[(addr&7)+2](addr,l>>8);
219: nbic_write_reg[(addr&7)+3](addr,l);
220: }
221: }
222:
223: void nbic_reg_wput(uaecptr addr, Uint32 w) {
224: if (addr&1) {
225: Log_Printf(LOG_WARN, "[NBIC] Unaligned access at %08X.",addr);
226: abort();
227: }
228:
229: if ((addr&0x0000FFFF)>7) {
230: nbic_bus_error_write(addr,0);
231: } else {
232: nbic_write_reg[addr&7](addr,w>>8);
233: nbic_write_reg[(addr&7)+1](addr,w);
234: }
235: }
236:
237: void nbic_reg_bput(uaecptr addr, Uint32 b) {
238: if ((addr&0x0000FFFF)>7) {
239: nbic_bus_error_write(addr,0);
240: } else {
241: nbic_write_reg[addr&7](addr,b);
242: }
243: }
244:
245:
246: /* NeXTbus CPU board slot space access */
247: static Uint8 (*nbic_read_cpu_slot[32])(Uint32) = {
248: nbic_bus_error_read, nbic_bus_error_read, nbic_bus_error_read, nbic_bus_error_read,
249: nbic_bus_error_read, nbic_bus_error_read, nbic_bus_error_read, nbic_bus_error_read,
250: nbic_intstatus_read, nbic_zero_read, nbic_zero_read, nbic_zero_read,
251: nbic_intmask_read, nbic_zero_read, nbic_zero_read, nbic_zero_read,
252:
253: nbic_id_read0, nbic_zero_read, nbic_zero_read, nbic_zero_read,
254: nbic_id_read1, nbic_zero_read, nbic_zero_read, nbic_zero_read,
255: nbic_id_read2, nbic_zero_read, nbic_zero_read, nbic_zero_read,
256: nbic_id_read3, nbic_zero_read, nbic_zero_read, nbic_zero_read,
257: };
258:
259: static void (*nbic_write_cpu_slot[32])(Uint32, Uint8) = {
260: nbic_bus_error_write, nbic_bus_error_write, nbic_bus_error_write, nbic_bus_error_write,
261: nbic_bus_error_write, nbic_bus_error_write, nbic_bus_error_write, nbic_bus_error_write,
262: nbic_bus_error_write, nbic_bus_error_write, nbic_bus_error_write, nbic_bus_error_write,
263: nbic_intmask_write, nbic_zero_write, nbic_zero_write, nbic_zero_write,
264:
265: nbic_bus_error_write, nbic_bus_error_write, nbic_bus_error_write, nbic_bus_error_write,
266: nbic_bus_error_write, nbic_bus_error_write, nbic_bus_error_write, nbic_bus_error_write,
267: nbic_bus_error_write, nbic_bus_error_write, nbic_bus_error_write, nbic_bus_error_write,
268: nbic_bus_error_write, nbic_bus_error_write, nbic_bus_error_write, nbic_bus_error_write
269: };
270:
271: Uint32 nb_cpu_slot_lget(Uint32 addr) {
272: Uint32 val = 0;
273:
274: if (addr&3) {
275: Log_Printf(LOG_WARN, "[NBIC] Unaligned access at %08X.",addr);
276: abort();
277: }
278:
279: if ((addr&0x00FFFFFF)<0x00FFFFE8) {
280: nbic_bus_error_read(addr);
281: } else {
282: val = nbic_read_cpu_slot[addr&0x1F](addr)<<24;
283: val |= nbic_read_cpu_slot[(addr&0x1F)+1](addr+1)<<16;
284: val |= nbic_read_cpu_slot[(addr&0x1F)+2](addr+2)<<8;
285: val |= nbic_read_cpu_slot[(addr&0x1F)+3](addr+3);
286: }
287:
288: return val;
289: }
290:
291: Uint16 nb_cpu_slot_wget(Uint32 addr) {
292: Uint32 val = 0;
293:
294: if (addr&1) {
295: Log_Printf(LOG_WARN, "[NBIC] Unaligned access at %08X.",addr);
296: abort();
297: }
298:
299: if ((addr&0x00FFFFFF)<0x00FFFFE8) {
300: nbic_bus_error_read(addr);
301: } else {
302: val = nbic_read_cpu_slot[addr&0x1F](addr)<<8;
303: val |= nbic_read_cpu_slot[(addr&0x1F)+1](addr+1)<<16;
304: }
305:
306: return val;
307: }
308:
309: Uint8 nb_cpu_slot_bget(Uint32 addr) {
310: if ((addr&0x00FFFFFF)<0x00FFFFE8) {
311: return nbic_bus_error_read(addr);
312: } else {
313: return nbic_read_cpu_slot[addr&0x1F](addr);
314: }
315: }
316:
317: void nb_cpu_slot_lput(Uint32 addr, Uint32 l) {
318: if (addr&3) {
319: Log_Printf(LOG_WARN, "[NBIC] Unaligned access at %08X.",addr);
320: abort();
321: }
322:
323: if ((addr&0x00FFFFFF)<0x00FFFFE8) {
324: nbic_bus_error_write(addr,0);
325: } else {
326: nbic_write_cpu_slot[addr&0x1F](addr,l>>24);
327: nbic_write_cpu_slot[(addr&0x1F)+1](addr,l>>16);
328: nbic_write_cpu_slot[(addr&0x1F)+2](addr,l>>8);
329: nbic_write_cpu_slot[(addr&0x1F)+3](addr,l);
330: }
331: }
332:
333: void nb_cpu_slot_wput(Uint32 addr, Uint16 w) {
334: if (addr&1) {
335: Log_Printf(LOG_WARN, "[NBIC] Unaligned access at %08X.",addr);
336: abort();
337: }
338:
339: if ((addr&0x00FFFFFF)<0x00FFFFE8) {
340: nbic_bus_error_write(addr,0);
341: } else {
342: nbic_write_cpu_slot[addr&0x1F](addr,w>>8);
343: nbic_write_cpu_slot[(addr&0x1F)+1](addr,w);
344: }
345: }
346:
347: void nb_cpu_slot_bput(Uint32 addr, Uint8 b) {
348: if ((addr&0x00FFFFFF)<0x00FFFFE8) {
349: nbic_bus_error_write(addr,0);
350: } else {
351: nbic_write_cpu_slot[addr&0x1F](addr,b);
352: }
353: }
354:
355:
356:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.