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