|
|
1.1 root 1: #include "main.h"
2: #include "configuration.h"
3: #include "m68000.h"
4: #include "sysdeps.h"
5: #include "dimension.hpp"
6: #include "nd_mem.hpp"
7: #include "log.h"
8:
9: /* --------- NEXTDIMENSION MEMORY ---------- */
10:
11: /* NeXTdimension board memory */
12: #define ND_RAM_START 0xF8000000
13: #define ND_RAM_SIZE 0x04000000
14: #define ND_RAM_MASK 0x03FFFFFF
15:
16: #define ND_VRAM_START 0xFE000000
17: #define ND_VRAM_SIZE 0x00400000
18: #define ND_VRAM_MASK 0x003FFFFF
19:
20: #define ND_EEPROM_START 0xFFF00000
21: #define ND_EEPROM_SIZE 0x00020000
22: #define ND_EEPROM_MASK 0x0001FFFF
23:
24: /* RAM banks */
25: #define ND_RAM_BANKSIZE 0x01000000
26: #define ND_RAM_BANKMASK 0x03000000
27:
28: /* NeXTdimension dither memory */
29: #define ND_DMEM_START 0xFF000000
30: #define ND_DMEM_SIZE 0x00000200
31: #define ND_DMEM_MASK 0x000001FF
32:
33: /* NeXTdimension board devices */
34: #define ND_IO_START 0xFF800000
35: #define ND_IO_SIZE 0x00004000
36: #define ND_IO_MASK 0x00003FFF
37:
38: /* NeXTdimension board RAMDAC */
39: #define ND_RAMDAC_START 0xFF200000
40: #define ND_RAMDAC_SIZE 0x00001000
41: #define ND_RAMDAC_MASK 0x00000FFF
42:
43: /* NeXTdimension board data path */
44: #define ND_DP_START 0xF0000000
45: #define ND_DP_SIZE 0x00001000
46: #define ND_DP_MASK 0x00000FFF
47:
48: /* NeXTdimension unknown registers */
49: #define ND_CSR_START 0xFF400000
50: #define ND_CSR_SIZE 0x00000200
51: #define ND_CSR_MASK 0x000001FF
52:
53: /* Function to fix address for ROM access */
54: static uaecptr nd_rom_addr_fix(uaecptr addr)
55: {
56: #if ND_STEP
57: addr >>= 2;
58: #else
59: addr &= ~3;
60: addr |= (addr>>17)&3;
61: #endif
62: addr &= ND_EEPROM_MASK;
63: return addr;
64: }
65:
66: /* Memory banks */
67:
68: /* NeXTdimension RAM */
69:
70: class ND_RAM : public ND_Addrbank {
71: Uint8* base;
72: Uint32 mask;
73: public:
74: ND_RAM(NextDimension* nd, int bank) : ND_Addrbank(nd), base(nd->ram), mask(nd->bankmask[bank]) {}
75:
76: Uint32 lget(Uint32 addr) {
77: addr &= mask;
78: return do_get_mem_long(base + addr);
79: }
80:
81: Uint32 wget(Uint32 addr) {
82: addr &= mask;
83: return do_get_mem_word(base + addr);
84: }
85:
86: Uint32 bget(Uint32 addr) {
87: addr &= mask;
88: return base[addr];
89: }
90:
91: void lput(Uint32 addr, Uint32 l) {
92: addr &= mask;
93: do_put_mem_long(base + addr, l);
94: }
95:
96: void wput(Uint32 addr, Uint32 w) {
97: addr &= mask;
98: do_put_mem_word(base + addr, w);
99: }
100:
101: void bput(Uint32 addr, Uint32 b) {
102: addr &= mask;
103: base[addr] = b;
104: }
105: };
106:
107: class ND_Empty : public ND_Addrbank {
108: public:
109: ND_Empty(NextDimension* nd) : ND_Addrbank(nd) {}
110:
111: Uint32 lget(Uint32 addr) {
112: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: empty memory bank lget at %08X\n", nd->slot,addr);
113: return 0;
114: }
115:
116: Uint32 wget(Uint32 addr) {
117: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: empty memory bank wget at %08X\n", nd->slot,addr);
118: return 0;
119: }
120:
121: Uint32 bget(Uint32 addr) {
122: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: empty memory bank bget at %08X\n", nd->slot,addr);
123: return 0;
124: }
125:
126: void lput(Uint32 addr, Uint32 l) {
127: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: empty memory bank lput at %08X\n", nd->slot,addr);
128: }
129:
130: void wput(Uint32 addr, Uint32 w) {
131: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: empty memory bank wput at %08X\n", nd->slot,addr);
132: }
133:
134: void bput(Uint32 addr, Uint32 b) {
135: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: empty memory bank bput at %08X\n",nd->slot,addr);
136: }
137: };
138:
139: /* NeXTdimension VRAM */
140: /* stored as ARGB for faster blitting, assuming aligned access for 32 bit */
141:
142: class ND_VRAM : public ND_Addrbank {
143: Uint8* base;
144: public:
145: ND_VRAM(NextDimension* nd) : ND_Addrbank(nd), base(nd->vram) {
146: // sanity checks for ARGB mem access
147: lput(0, 0x12345678);
148: if(lget(0) != 0x12345678) {fprintf(stderr, "ND_VRAM: 32 bit access check failed\n"); goto error;}
149:
150: if(bget(0) != 0x12) {fprintf(stderr, "ND_VRAM: 8 bit access 0 check failed\n"); goto error;}
151: if(bget(1) != 0x34) {fprintf(stderr, "ND_VRAM: 8 bit access 1 check failed\n"); goto error;}
152: if(bget(2) != 0x56) {fprintf(stderr, "ND_VRAM: 8 bit access 2 check failed\n"); goto error;}
153: if(bget(3) != 0x78) {fprintf(stderr, "ND_VRAM: 8 bit access 3 check failed\n"); goto error;}
154:
155: if(wget(0) != 0x1234) {fprintf(stderr, "ND_VRAM: 16 bit access 0 check failed\n"); goto error;}
156: if(wget(2) != 0x5678) {fprintf(stderr, "ND_VRAM: 16 bit access 2 check failed\n"); goto error;}
157:
158: wput(0, 0x7654);
159: wput(2, 0x3210);
160: if(lget(0) != 0x76543210) {fprintf(stderr, "ND_VRAM: 32 bit access check failed (wput)\n"); goto error;}
161:
162: bput(0, 0x12);
163: bput(1, 0x34);
164: bput(2, 0x56);
165: bput(3, 0x78);
166: if(lget(0) != 0x12345678) {fprintf(stderr, "ND_VRAM: 32 bit access check failed (bput)\n"); goto error;}
167:
168: return;
169: error:
170: exit(1);
171: }
172:
173: Uint32 lget(Uint32 addr) {
174: addr &= ND_VRAM_MASK;
175: return
176: base[addr+3] |
177: (base[addr+0] << 8) |
178: (base[addr+1] << 16) |
179: (base[addr+2] << 24);
180: }
181:
182: void lput(Uint32 addr, Uint32 l) {
183: addr &= ND_VRAM_MASK;
184: base[addr+3] = l;
185: base[addr+0] = l >> 8;
186: base[addr+1] = l >> 16;
187: base[addr+2] = l >> 24;
188: }
189:
190: Uint32 wget(Uint32 addr) {
191: addr &= ND_VRAM_MASK;
192: return (bget(addr) << 8) | bget(addr+1);
193: }
194:
195: void wput(Uint32 addr, Uint32 w) {
196: addr &= ND_VRAM_MASK;
197: bput(addr, w >> 8);
198: bput(addr+1, w);
199: }
200:
201: Uint32 bget(Uint32 addr) {
202: addr &= ND_VRAM_MASK;
203: switch(addr&3) {
204: case 0: return base[(addr&~3)+2];
205: case 1: return base[(addr&~3)+1];
206: case 2: return base[(addr&~3)+0];
207: case 3: return base[(addr&~3)+3];
208: }
209: return 0;
210: }
211:
212: void bput(Uint32 addr, Uint32 b) {
213: addr &= ND_VRAM_MASK;
214: switch(addr&3) {
215: case 0: base[(addr&~3)+2] = b; break;
216: case 1: base[(addr&~3)+1] = b; break;
217: case 2: base[(addr&~3)+0] = b; break;
218: case 3: base[(addr&~3)+3] = b; break;
219: }
220: }
221: };
222:
223: /* NeXTdimension ROM */
224:
225: class ND_ROM : public ND_Addrbank {
226: public:
227: ND_ROM(NextDimension* nd) : ND_Addrbank(nd) {}
228:
229: Uint32 lget(Uint32 addr) {
230: addr = nd_rom_addr_fix(addr);
231: return (nd->rom_read(addr) << 24); /* byte lane at msb */
232: }
233:
234: Uint32 wget(Uint32 addr) {
235: addr = nd_rom_addr_fix(addr);
236: return (nd->rom_read(addr) << 8); /* byte lane at msb */
237: }
238:
239: Uint32 bget(Uint32 addr) {
240: addr = nd_rom_addr_fix(addr);
241: return nd->rom_read(addr);
242: }
243:
244: Uint32 cs8get(Uint32 addr) {
245: addr &= ND_EEPROM_MASK;
246: return nd->rom[addr];
247: }
248:
249: void lput(Uint32 addr, Uint32 l) {
250: addr = nd_rom_addr_fix(addr);
251: nd->rom_write(addr, l >> 24);
252: }
253:
254: void wput(Uint32 addr, Uint32 w) {
255: addr = nd_rom_addr_fix(addr);
256: nd->rom_write(addr, w >> 8);
257: }
258:
259: void bput(Uint32 addr, Uint32 b) {
260: addr = nd_rom_addr_fix(addr);
261: nd->rom_write(addr, b);
262: }
263: };
264:
265: /* Unknown register access functions (memory controller step 1) */
266: #if ND_STEP
267:
268: class ND_CSR : public ND_Addrbank {
269: public:
270: ND_CSR(NextDimension* nd) : ND_Addrbank(nd) {}
271:
272: Uint32 lget(Uint32 addr) {
273: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: Board CSR lget at %08X\n", nd->slot,addr);
274: return 0;
275: }
276:
277: Uint32 wget(Uint32 addr) {
278: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: Board CSR wget at %08X\n",nd->slot,addr);
279: return 0;
280: }
281:
282: Uint32 bget(Uint32 addr) {
283: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: Board CSR bget at %08X\n",nd->slot,addr);
284: return 0;
285: }
286:
287: void lput(Uint32 addr, Uint32 l) {
288: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: Board CSR lput at %08X: %08X\n",nd->slot,addr,l);
289: }
290:
291: void wput(Uint32 addr, Uint32 w) {
292: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: Board CSR wput at %08X: %04X\n",nd->slot,addr,w);
293: }
294:
295: void bput(Uint32 addr, Uint32 b) {
296: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: Board CSR bput at %08X: %02X\n",nd->slot,addr,b);
297: }
298: };
299: #endif
300:
301: /* NeXTdimension dither memory & datapath */
302:
303: class ND_DMEM : public ND_Addrbank {
304: public:
305: ND_DMEM(NextDimension* nd) : ND_Addrbank(nd) {}
306:
307: Uint32 lget(Uint32 addr) {
308: addr &= ND_DP_MASK;
309: return addr < ND_DMEM_SIZE ? do_get_mem_long(nd->dmem + addr) : nd->dp.lget(addr);
310: }
311:
312: Uint32 wget(Uint32 addr) {
313: addr &= ND_DP_MASK;
314: return addr < ND_DMEM_SIZE ? do_get_mem_word(nd->dmem + addr) : nd->dp.lget(addr);
315: }
316:
317: Uint32 bget(Uint32 addr) {
318: addr &= ND_DP_MASK;
319: return addr < ND_DMEM_SIZE ? do_get_mem_byte(nd->dmem + addr) : nd->dp.lget(addr);
320: }
321:
322: void lput(Uint32 addr, Uint32 l) {
323: addr &= ND_DP_MASK;
324: if(addr < ND_DMEM_SIZE)
325: do_put_mem_long(nd->dmem + addr, l);
326: else
327: nd->dp.lput(addr, l);
328: }
329:
330: void wput(Uint32 addr, Uint32 w) {
331: addr &= ND_DP_MASK;
332: if(addr < ND_DMEM_SIZE)
333: do_put_mem_word(nd->dmem + addr, w);
334: else
335: nd->dp.lput(addr, w);
336: }
337:
338: void bput(Uint32 addr, Uint32 b) {
339: addr &= ND_DP_MASK;
340: if(addr < ND_DMEM_SIZE)
341: do_put_mem_byte(nd->dmem + addr, b);
342: else
343: nd->dp.lput(addr, b);
344: }
345: };
346:
347: /* Illegal access functions */
348:
349: ND_Addrbank::ND_Addrbank(NextDimension* nd) : nd(nd) {}
350:
351: Uint32 ND_Addrbank::lget(Uint32 addr) {
352: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: Illegal lget at %08X\n",nd->slot,addr);
353: return 0;
354: }
355:
356: Uint32 ND_Addrbank::wget(Uint32 addr) {
357: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: Illegal wget at %08X\n",nd->slot,addr);
358: return 0;
359: }
360:
361: Uint32 ND_Addrbank::bget(Uint32 addr) {
362: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: Illegal bget at %08X\n",nd->slot,addr);
363: return 0;
364: }
365:
366: Uint32 ND_Addrbank::cs8get(Uint32 addr) {
367: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: Illegal cs8get at %08X\n",nd->slot,addr);
368: return 0;
369: }
370:
371: void ND_Addrbank::lput(Uint32 addr, Uint32 l) {
372: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: Illegal lput at %08X\n",nd->slot,addr);
373: }
374:
375: void ND_Addrbank::wput(Uint32 addr, Uint32 w) {
376: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: Illegal wput at %08X\n",nd->slot,addr);
377: }
378:
379: void ND_Addrbank::bput(Uint32 addr, Uint32 b) {
380: Log_Printf(LOG_ND_MEM, "[ND] Slot %i: Illegal bput at %08X\n",nd->slot,addr);
381: }
382:
383: /* NeXTdimension device space */
384:
385: class ND_IO : public ND_Addrbank {
386: public:
387: ND_IO(NextDimension* nd) : ND_Addrbank(nd) {}
388:
389: Uint32 lget(Uint32 addr) {
390: return nd->mc.read(addr);
391: }
392:
393: Uint32 wget(Uint32 addr) {return 0;}
394:
395: Uint32 bget(Uint32 addr) {return 0;}
396:
397: void lput(Uint32 addr, Uint32 l) {
398: nd->mc.write(addr, l);
399: }
400:
401: void wput(Uint32 addr, Uint32 w) {}
402: void bput(Uint32 addr, Uint32 b) {}
403: };
404:
405: /* NeXTdimension RAMDAC */
406:
407: class ND_RAMDAC : public ND_Addrbank {
408: public:
409: ND_RAMDAC(NextDimension* nd) : ND_Addrbank(nd) {}
410:
411: Uint32 lget(Uint32 addr) {
412: return bt463_bget(&nd->ramdac, addr) << 24;
413: }
414:
415: Uint32 wget(Uint32 addr) {
416: return bt463_bget(&nd->ramdac, addr) << 8;
417: }
418:
419: Uint32 bget(Uint32 addr) {
420: return bt463_bget(&nd->ramdac, addr);
421: }
422:
423: void lput(Uint32 addr, Uint32 l) {
424: bt463_bput(&nd->ramdac, addr, l >> 24);
425: }
426:
427: void wput(Uint32 addr, Uint32 w) {
428: bt463_bput(&nd->ramdac, addr, w >> 8);
429: }
430:
431: void bput(Uint32 addr, Uint32 b) {
432: bt463_bput(&nd->ramdac, addr, b);
433: }
434: };
435:
436: void NextDimension::map_banks (ND_Addrbank *bank, int start, int size) {
437: for (int bnr = start; bnr < start + size; bnr++)
438: nd_put_mem_bank (bnr << 16, bank);
439: return;
440: }
441:
442: void NextDimension::init_mem_banks(void) {
443: ND_Addrbank* nd_illegal_bank = new ND_Addrbank(this);
444: for (int i = 0; i < 65536; i++)
445: nd_put_mem_bank(i<<16, nd_illegal_bank);
446: }
447:
448: #define write_log printf
449:
450: void NextDimension::mem_init(void) {
451: write_log("[ND] Slot %i: Memory init: Memory size: %iMB\n", slot,
452: Configuration_CheckDimensionMemory(ConfigureParams.Dimension.board[ND_NUM(slot)].nMemoryBankSize));
453:
454: /* Initialize banks with error memory */
455: init_mem_banks();
456:
457: /* Clear first 4k of memory for m68k ROM polling code */
458: memset(ram, 0, 4096 * sizeof(Uint8));
459:
460: /* Map main memory */
461:
462: for(int bank = 0; bank < 4; bank++) {
463: if (ConfigureParams.Dimension.board[ND_NUM(slot)].nMemoryBankSize[bank]) {
464: bankmask[bank] = ND_RAM_BANKMASK|((ConfigureParams.Dimension.board[ND_NUM(slot)].nMemoryBankSize[bank]<<20)-1);
465: map_banks(new ND_RAM(this, bank), (ND_RAM_START+(bank*ND_RAM_BANKSIZE))>>16, ND_RAM_BANKSIZE >> 16);
466: write_log("[ND] Slot %i: Mapping main memory bank%d at $%08x: %iMB\n", slot, bank,
467: (ND_RAM_START+(bank*ND_RAM_BANKSIZE)), ConfigureParams.Dimension.board[ND_NUM(slot)].nMemoryBankSize[0]);
468: } else {
469: bankmask[bank] = 0;
470: map_banks(new ND_Empty(this), (ND_RAM_START+(bank*ND_RAM_BANKSIZE))>>16, ND_RAM_BANKSIZE >> 16);
471: write_log("[ND] Slot %i: Mapping main memory bank%d at $%08x: empty\n", slot, bank,
472: (ND_RAM_START+(bank*ND_RAM_BANKSIZE)));
473: }
474: }
475:
476: write_log("[ND] Slot %i: Mapping video memory at $%08x: %iMB\n", slot,
477: ND_VRAM_START, ND_VRAM_SIZE/(1024*1024));
478: map_banks(new ND_VRAM(this), ND_VRAM_START>>16, (4*ND_VRAM_SIZE)>>16);
479:
480: write_log("[ND] Slot %i: Mapping ROM at $%08x: %ikB\n", slot,
481: ND_EEPROM_START, ND_EEPROM_SIZE/1024);
482: map_banks(new ND_ROM(this), ND_EEPROM_START>>16, (ND_EEPROM_SIZE*8)>>16);
483: rom_load();
484:
485: write_log("[ND] Slot %i: Mapping dither memory and data path at $%08x: %ibyte\n", slot,
486: ND_DMEM_START, ND_DMEM_SIZE);
487: map_banks(new ND_DMEM(this), ND_DMEM_START>>16, 1);
488:
489: write_log("[ND] Slot %i: Mapping IO memory at $%08x\n", slot, ND_IO_START);
490: map_banks(new ND_IO(this), ND_IO_START>>16, 1);
491:
492: write_log("[ND] Slot %i: Mapping RAMDAC registers at $%08x\n", slot, ND_RAMDAC_START);
493: map_banks(new ND_RAMDAC(this), ND_RAMDAC_START>>16, 1);
494: #if ND_STEP
495: write_log("[ND] Slot %i: Mapping board CSR at $%08x\n", slot, ND_CSR_START);
496: map_banks(new ND_CSR(this), ND_CSR_START>>16, 1);
497: #endif
498: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.