|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * Gayle (and motherboard resources) memory bank
5: *
6: * (c) 2006 - 2007 Toni Wilen
7: */
8:
9: #define GAYLE_LOG 0
10: #define IDE_LOG 0
11: #define MBRES_LOG 0
12:
13: #include "sysconfig.h"
14: #include "sysdeps.h"
15:
16: #include "options.h"
17:
18: #include "memory.h"
19: #include "custom.h"
20: #include "newcpu.h"
21: #include "gayle.h"
22: #include "zfile.h"
23: #include "filesys.h"
24: #include "savestate.h"
25: #include "gui.h"
26:
27: /*
28: D80000 to D8FFFF 64 KB SPARE chip select
29: D90000 to D9FFFF 64 KB ARCNET chip select
30: DA0000 to DA3FFF 16 KB IDE drive
31: DA4000 to DA4FFF 16 KB IDE reserved
32: DA8000 to DAFFFF 32 KB Credit Card and IDE configregisters
33: DB0000 to DBFFFF 64 KB Not used(reserved for external IDE)
34: * DC0000 to DCFFFF 64 KB Real Time Clock(RTC)
35: DD0000 to DDFFFF 64 KB A3000 DMA controller
36: DD0000 to DD1FFF A4000 DMAC
37: DD2000 to DDFFFF A4000 IDE
38: DE0000 to DEFFFF 64 KB Motherboard resources
39: */
40:
41: #define NCR_OFFSET 0x40
42:
43: /* Gayle definitions from Linux drivers */
44:
45: /* PCMCIA stuff */
46:
47: #define GAYLE_RAM (0x600000+zTwoBase)
48: #define GAYLE_RAMSIZE (0x400000)
49: #define GAYLE_ATTRIBUTE (0xa00000+zTwoBase)
50: #define GAYLE_ATTRIBUTESIZE (0x020000)
51: #define GAYLE_IO (0xa20000+zTwoBase) /* 16bit and even 8bit registers */
52: #define GAYLE_IOSIZE (0x010000)
53: #define GAYLE_IO_8BITODD (0xa30000+zTwoBase) /* odd 8bit registers */
54: /* offset for accessing odd IO registers */
55: #define GAYLE_ODD (GAYLE_IO_8BITODD-GAYLE_IO-1)
56:
57: #define GAYLE_ADDRESS (0xda8000) /* gayle main registers base address */
58: #define GAYLE_RESET (0xa40000) /* write 0x00 to start reset,
59: read 1 byte to stop reset */
60: /* GAYLE_CARDSTATUS bit def */
61: #define GAYLE_CS_CCDET 0x40 /* credit card detect */
62: #define GAYLE_CS_BVD1 0x20 /* battery voltage detect 1 */
63: #define GAYLE_CS_SC 0x20 /* credit card status change */
64: #define GAYLE_CS_BVD2 0x10 /* battery voltage detect 2 */
65: #define GAYLE_CS_DA 0x10 /* digital audio */
66: #define GAYLE_CS_WR 0x08 /* write enable (1 == enabled) */
67: #define GAYLE_CS_BSY 0x04 /* credit card busy */
68: #define GAYLE_CS_IRQ 0x04 /* interrupt request */
69:
70: /* GAYLE_CONFIG bit def
71: (bit 0-1 for program voltage, bit 2-3 for access speed */
72: #define GAYLE_CFG_0V 0x00
73: #define GAYLE_CFG_5V 0x01
74: #define GAYLE_CFG_12V 0x02
75:
76: #define GAYLE_CFG_100NS 0x08
77: #define GAYLE_CFG_150NS 0x04
78: #define GAYLE_CFG_250NS 0x00
79: #define GAYLE_CFG_720NS 0x0c
80:
81: /* IDE stuff */
82:
83: /* Bases of the IDE interfaces */
84: #define GAYLE_BASE_4000 0xdd2020 /* A4000/A4000T */
85: #define GAYLE_BASE_1200 0xda0000 /* A1200/A600 and E-Matrix 530 */
86: /* IDE drive registers */
87: #define IDE_DATA 0x00
88: #define IDE_ERROR 0x01 /* see err-bits */
89: #define IDE_NSECTOR 0x02 /* nr of sectors to read/write */
90: #define IDE_SECTOR 0x03 /* starting sector */
91: #define IDE_LCYL 0x04 /* starting cylinder */
92: #define IDE_HCYL 0x05 /* high byte of starting cyl */
93: #define IDE_SELECT 0x06 /* 101dhhhh , d=drive, hhhh=head */
94: #define IDE_STATUS 0x07 /* see status-bits */
95: #define IDE_DEVCON 0x0406
96: #define IDE_DRVADDR 0x0407
97: /* STATUS bits */
98: #define IDE_STATUS_ERR 0x01
99: #define IDE_STATUS_IDX 0x02
100: #define IDE_STATUS_DRQ 0x08
101: #define IDE_STATUS_DSC 0x10
102: #define IDE_STATUS_DRDY 0x40
103: #define IDE_STATUS_BSY 0x80
104: /* ERROR bits */
105: #define IDE_ERR_ABRT 0x04
106:
107: /*
108: * These are at different offsets from the base
109: */
110: #define GAYLE_IRQ_4000 0x3020 /* MSB = 1, Harddisk is source of interrupt */
111: #define GAYLE_IRQ_1200 0x9000
112: #define GAYLE_INT_1200 0xA000
113:
114: /* GAYLE_IRQ bit def */
115: #define GAYLE_IRQ_IDE 0x80
116: #define GAYLE_IRQ_CCDET 0x40
117: #define GAYLE_IRQ_BVD1 0x20
118: #define GAYLE_IRQ_SC 0x20
119: #define GAYLE_IRQ_BVD2 0x10
120: #define GAYLE_IRQ_DA 0x10
121: #define GAYLE_IRQ_WR 0x08
122: #define GAYLE_IRQ_BSY 0x04
123: #define GAYLE_IRQ_IRQ 0x04
124: #define GAYLE_IRQ_IDEACK1 0x02
125: #define GAYLE_IRQ_IDEACK0 0x01
126:
127: struct ide_hdf
128: {
129: uae_u8 secbuf[512 * 256];
130: uae_u8 multiple_mode;
131: uae_u8 status;
132: int irq_delay;
133: int num;
134: };
135:
136: static struct ide_hdf idedrive[4];
137:
138: static int gayle_id_cnt;
139: static uae_u8 gayle_irq, gayle_intena;
140: static uae_u8 ide_select, ide_nsector, ide_sector, ide_lcyl, ide_hcyl, ide_devcon, ide_error, ide_feat;
141: static uae_u8 ide_nsector2, ide_sector2, ide_lcyl2, ide_hcyl2, ide_feat2;
142: static int ide_drv, ide2, ide_splitter;
143:
144: static struct ide_hdf *ide;
145:
146: STATIC_INLINE void pw (int offset, uae_u16 w)
147: {
148: ide->secbuf[offset * 2 + 0] = (uae_u8)w;
149: ide->secbuf[offset * 2 + 1] = w >> 8;
150: }
151:
152: static void ps (int offset, char *s, int max)
153: {
154: int i, len;
155:
156: offset *= 2;
157: len = strlen(s);
158: for (i = 0; i < max; i++) {
159: char c = ' ';
160: if (i < len)
161: c = s[i];
162: ide->secbuf[offset ^ 1] = c;
163: offset++;
164: }
165: }
166:
167: static void ide_interrupt(void)
168: {
169: ide->status |= IDE_STATUS_BSY;
170: ide->irq_delay = 2;
171: }
172:
173: static void ide_interrupt_do(struct ide_hdf *ide)
174: {
175: ide->status &= ~IDE_STATUS_BSY;
176: if (gayle_intena & GAYLE_IRQ_IDE) {
177: gayle_irq |= GAYLE_IRQ_IDE;
178: INTREQ (0x8000 | 0x0008);
179: }
180: }
181:
182: static void ide_fail(void)
183: {
184: ide_error |= IDE_ERR_ABRT;
185: #if 0
186: if (ide_drv == 1 && idedrive[ide2 + 1].hdhfd.size == 0)
187: idedrive[ide2].status |= IDE_STATUS_ERR;
188: #endif
189: ide->status |= IDE_STATUS_ERR;
190: ide_interrupt();
191: }
192:
193: static void ide_recalibrate(void)
194: {
195: write_log ("IDE%d recalibrate\n", ide->num);
196: ide_sector = 0;
197: ide_lcyl = ide_hcyl = 0;
198: ide_interrupt();
199: }
200:
201: static void ide_identify_drive(void)
202: {
203: int totalsecs;
204: int v;
205:
206: ide_fail();
207: return;
208: }
209:
210: static void ide_initialize_drive_parameters(void)
211: {
212: ide_error |= IDE_ERR_ABRT;
213: ide->status |= IDE_STATUS_ERR;
214: ide_interrupt();
215: }
216:
217: static void ide_set_multiple_mode(void)
218: {
219: write_log ("IDE%d drive multiple mode = %d\n", ide->num, ide_nsector);
220: ide->multiple_mode = ide_nsector;
221: ide_interrupt();
222: }
223:
224: static void ide_set_features(void)
225: {
226: write_log ("IDE%d set features %02.2X (%02.2X)\n", ide->num, ide_feat, ide_nsector);
227: ide_fail();
228: }
229:
230: static void ide_read_sectors(int multi)
231: {
232: ide_fail();
233: }
234:
235: static void ide_write_sectors(int multi)
236: {
237: ide_fail();
238: }
239:
240: static void ide_do_command(uae_u8 cmd)
241: {
242: if (IDE_LOG > 1)
243: write_log ("**** IDE%d command %02.2X\n", ide->num, cmd);
244: ide->status &= ~(IDE_STATUS_DRDY | IDE_STATUS_DRQ | IDE_STATUS_ERR);
245: ide_error = 0;
246:
247: if (cmd == 0x10) { /* recalibrate */
248: ide_recalibrate();
249: } else if (cmd == 0xec) { /* identify drive */
250: ide_identify_drive();
251: } else if (cmd == 0x91) { /* initialize drive parameters */
252: ide_initialize_drive_parameters();
253: } else if (cmd == 0xc6) { /* set multiple mode */
254: ide_set_multiple_mode();
255: } else if (cmd == 0x20 || cmd == 0x21) { /* read sectors */
256: ide_read_sectors(0);
257: } else if (cmd == 0x30 || cmd == 0x31) { /* write sectors */
258: ide_write_sectors(0);
259: } else if (cmd == 0xc4) { /* read multiple */
260: ide_read_sectors(1);
261: } else if (cmd == 0xc5) { /* write multiple */
262: ide_write_sectors(1);
263: } else if (cmd == 0x50) { /* format track (nop) */
264: ide_interrupt();
265: } else if (cmd == 0xa1) { /* ATAPI identify (IDE HD is not ATAPI) */
266: ide_fail();
267: } else if (cmd == 0xef) { /* set features */
268: ide_set_features();
269: } else {
270: ide_fail();
271: write_log ("IDE: unknown command %x\n", cmd);
272: }
273: }
274:
275: static uae_u16 ide_get_data (void)
276: {
277: if (IDE_LOG > 0)
278: write_log ("IDE%d DATA read without DRQ!?\n", ide->num);
279: return 0xffff;
280: }
281:
282: static void ide_put_data (uae_u16 v)
283: {
284: if (IDE_LOG > 0)
285: write_log ("IDE%d DATA write without DRQ!?\n", ide->num);
286: }
287:
288: static int get_ide_reg (uaecptr addr)
289: {
290: uaecptr a = addr;
291: addr &= 0xffff;
292: if (addr >= 0x3020 && addr <= 0x3021 && currprefs.cs_ide == 2)
293: return -1;
294: addr &= ~0x2020;
295: addr >>= 2;
296: ide2 = 0;
297: if (addr & 0x400) {
298: if (ide_splitter) {
299: ide2 = 2;
300: addr &= ~0x400;
301: }
302: }
303: ide = &idedrive[ide_drv + ide2];
304: return addr;
305: }
306:
307: static uae_u32 ide_read (uaecptr addr)
308: {
309: int ide_reg;
310: uae_u8 v = 0;
311:
312: addr &= 0xffff;
313: if (IDE_LOG > 1 && addr != 0x2000 && addr != 0x2001 && addr != 0x2020 && addr != 0x2021 && addr != GAYLE_IRQ_1200)
314: write_log ("IDE_READ %08.8X PC=%X\n", addr, m68k_getpc ());
315: if (currprefs.cs_ide <= 0) {
316: if (addr == 0x201c) // AR1200 IDE detection hack
317: return 0x7f;
318: return 0xff;
319: }
320: if (addr >= GAYLE_IRQ_4000 && addr <= GAYLE_IRQ_4000 + 1 && currprefs.cs_ide == 2) {
321: uae_u8 v = gayle_irq;
322: gayle_irq = 0;
323: return v;
324: }
325: if (addr >= 0x4000) {
326: if (addr == GAYLE_IRQ_1200) {
327: if (currprefs.cs_ide == 1)
328: return gayle_irq;
329: return 0;
330: } else if (addr == GAYLE_INT_1200) {
331: if (currprefs.cs_ide == 1)
332: return gayle_intena;
333: return 0;
334: }
335: return 0;
336: }
337: ide_reg = get_ide_reg(addr);
338: /* Emulated "ide killer". Prevents long KS boot delay if no drives installed */
339: if (ide_reg == IDE_STATUS)
340: return 0x7f;
341: return 0xff;
342:
343: }
344:
345: static void ide_write (uaecptr addr, uae_u32 val)
346: {
347: int ide_reg;
348:
349: addr &= 0xffff;
350: ide_devcon &= ~0x80;
351: if (IDE_LOG > 1 && addr != 0x2000 && addr != 0x2001 && addr != 0x2020 && addr != 0x2021 && addr != GAYLE_IRQ_1200)
352: write_log ("IDE_WRITE %08.8X=%02.2X PC=%X\n", addr, (uae_u32)val & 0xff, m68k_getpc ());
353: if (currprefs.cs_ide <= 0)
354: return;
355: if (currprefs.cs_ide == 1) {
356: if (addr == GAYLE_IRQ_1200) {
357: gayle_irq = 0;
358: return;
359: }
360: if (addr == GAYLE_INT_1200) {
361: gayle_intena = val;
362: return;
363: }
364: }
365: if (addr >= 0x4000)
366: return;
367: ide_reg = get_ide_reg(addr);
368: if (IDE_LOG > 2 && ide_reg > 0)
369: write_log ("IDE%d register %d=%02.2X\n", ide->num, ide_reg, (uae_u32)val & 0xff);
370: switch (ide_reg)
371: {
372: case IDE_DRVADDR:
373: break;
374: case IDE_DEVCON:
375: ide_devcon = val;
376: break;
377: case IDE_DATA:
378: break;
379: case IDE_ERROR:
380: ide_feat2 = ide_feat;
381: ide_feat = val;
382: break;
383: case IDE_NSECTOR:
384: ide_nsector2 = ide_nsector;
385: ide_nsector = val;
386: break;
387: case IDE_SECTOR:
388: ide_sector2 = ide_sector;
389: ide_sector = val;
390: break;
391: case IDE_LCYL:
392: ide_lcyl2 = ide_lcyl;
393: ide_lcyl = val;
394: break;
395: case IDE_HCYL:
396: ide_hcyl2 = ide_hcyl;
397: ide_hcyl = val;
398: break;
399: case IDE_SELECT:
400: ide_select = val;
401: ide_drv = (val & 0x10) ? 1 : 0;
402: break;
403: case IDE_STATUS:
404: ide_do_command (val);
405: break;
406: }
407: }
408:
409: static int gayle_read (uaecptr addr)
410: {
411: uaecptr oaddr = addr;
412: uae_u32 v = 0;
413: #ifdef JIT
414: special_mem |= S_READ;
415: #endif
416: v = ide_read(addr);
417: if (GAYLE_LOG)
418: write_log ("GAYLE_READ %08.8X=%02.2X PC=%08.8X\n", oaddr, (uae_u32)v & 0xff, m68k_getpc ());
419: return v;
420: }
421: static void gayle_write (uaecptr addr, int val)
422: {
423: #ifdef JIT
424: special_mem |= S_WRITE;
425: #endif
426: if (GAYLE_LOG)
427: write_log ("GAYLE_WRITE %08.8X=%02.2X PC=%08.8X\n", addr, (uae_u32)val & 0xff, m68k_getpc ());
428: ide_write(addr, val);
429: }
430:
431: static uae_u32 gayle_lget (uaecptr) REGPARAM;
432: static uae_u32 gayle_wget (uaecptr) REGPARAM;
433: static uae_u32 gayle_bget (uaecptr) REGPARAM;
434: static void gayle_lput (uaecptr, uae_u32) REGPARAM;
435: static void gayle_wput (uaecptr, uae_u32) REGPARAM;
436: static void gayle_bput (uaecptr, uae_u32) REGPARAM;
437:
438: addrbank gayle_bank = {
439: gayle_lget, gayle_wget, gayle_bget,
440: gayle_lput, gayle_wput, gayle_bput,
441: default_xlate, default_check, NULL, "Gayle (low)"
442: };
443:
444: #if 0
445: static int isa4000t (uaecptr addr)
446: {
447: if (currprefs.cs_mbdmac != 2)
448: return 0;
449: if ((addr & 0xffff) >= (GAYLE_BASE_4000 & 0xffff))
450: return 0;
451: return 1;
452: }
453: #endif
454:
455: static uae_u32 REGPARAM2 gayle_lget (uaecptr addr)
456: {
457: uae_u32 v;
458: #ifdef JIT
459: special_mem |= S_READ;
460: #endif
461: v = gayle_wget (addr) << 16;
462: v |= gayle_wget (addr + 2);
463: return v;
464: }
465: static uae_u32 REGPARAM2 gayle_wget (uaecptr addr)
466: {
467: int ide_reg;
468: uae_u16 v;
469: #ifdef JIT
470: special_mem |= S_READ;
471: #endif
472: #if 0
473: if (isa4000t(addr)) {
474: addr -= NCR_OFFSET;
475: return (ncr_bget2 (addr) << 8) | ncr_bget2 (addr + 1);
476: }
477: #endif
478: ide_reg = get_ide_reg (addr);
479: if (ide_reg == IDE_DATA)
480: return ide_get_data ();
481: v = gayle_bget (addr) << 8;
482: v |= gayle_bget (addr + 1);
483: return v;
484: }
485: static uae_u32 REGPARAM2 gayle_bget (uaecptr addr)
486: {
487: #ifdef JIT
488: special_mem |= S_READ;
489: #endif
490: #if 0
491: if (isa4000t(addr)) {
492: addr -= NCR_OFFSET;
493: return ncr_bget2(addr);
494: }
495: #endif
496: return gayle_read (addr);
497: }
498:
499: static void REGPARAM2 gayle_lput (uaecptr addr, uae_u32 value)
500: {
501: #ifdef JIT
502: special_mem |= S_WRITE;
503: #endif
504: gayle_wput (addr, value >> 16);
505: gayle_wput (addr + 2, value & 0xffff);
506: }
507: static void REGPARAM2 gayle_wput (uaecptr addr, uae_u32 value)
508: {
509: int ide_reg;
510: #ifdef JIT
511: special_mem |= S_WRITE;
512: #endif
513: #if 0
514: if (isa4000t (addr)) {
515: addr -= NCR_OFFSET;
516: ncr_bput2 (addr, value >> 8);
517: ncr_bput2 (addr + 1, value);
518: return;
519: }
520: #endif
521: ide_reg = get_ide_reg (addr);
522: if (ide_reg == IDE_DATA) {
523: ide_put_data(value);
524: return;
525: }
526: gayle_bput (addr, value >> 8);
527: gayle_bput (addr + 1, value & 0xff);
528: }
529:
530: static void REGPARAM2 gayle_bput (uaecptr addr, uae_u32 value)
531: {
532: #ifdef JIT
533: special_mem |= S_WRITE;
534: #endif
535: #if 0
536: if (isa4000t(addr)) {
537: addr -= NCR_OFFSET;
538: ncr_bput2(addr, value);
539: return;
540: }
541: #endif
542: gayle_write (addr, value);
543: }
544:
545: static void gayle2_write(uaecptr addr, uae_u32 v)
546: {
547: gayle_id_cnt = 0;
548: }
549:
550: static uae_u32 gayle2_read(uaecptr addr)
551: {
552: uae_u8 v = 0;
553: addr &= 0xffff;
554: if (addr == 0x1000) {
555: /* Gayle ID */
556: if ((gayle_id_cnt & 3) == 2)
557: v = 0x7f;
558: else
559: v = 0x80;
560: gayle_id_cnt++;
561: }
562: return v;
563: }
564:
565: static uae_u32 gayle2_lget (uaecptr) REGPARAM;
566: static uae_u32 gayle2_wget (uaecptr) REGPARAM;
567: static uae_u32 gayle2_bget (uaecptr) REGPARAM;
568: static void gayle2_lput (uaecptr, uae_u32) REGPARAM;
569: static void gayle2_wput (uaecptr, uae_u32) REGPARAM;
570: static void gayle2_bput (uaecptr, uae_u32) REGPARAM;
571:
572: addrbank gayle2_bank = {
573: gayle2_lget, gayle2_wget, gayle2_bget,
574: gayle2_lput, gayle2_wput, gayle2_bput,
575: default_xlate, default_check, NULL, "Gayle (high)"
576: };
577:
578: static uae_u32 REGPARAM2 gayle2_lget (uaecptr addr)
579: {
580: uae_u32 v;
581: #ifdef JIT
582: special_mem |= S_READ;
583: #endif
584: v = gayle2_wget (addr) << 16;
585: v |= gayle2_wget (addr + 2);
586: return v;
587: }
588: static uae_u32 REGPARAM2 gayle2_wget (uaecptr addr)
589: {
590: uae_u16 v;
591: #ifdef JIT
592: special_mem |= S_READ;
593: #endif
594: v = gayle2_bget (addr) << 8;
595: v |= gayle2_bget (addr + 1);
596: return v;
597: }
598: static uae_u32 REGPARAM2 gayle2_bget (uaecptr addr)
599: {
600: #ifdef JIT
601: special_mem |= S_READ;
602: #endif
603: return gayle2_read (addr);
604: }
605:
606: static void REGPARAM2 gayle2_lput (uaecptr addr, uae_u32 value)
607: {
608: #ifdef JIT
609: special_mem |= S_WRITE;
610: #endif
611: gayle2_wput (addr, value >> 16);
612: gayle2_wput (addr + 2, value & 0xffff);
613: }
614:
615: static void REGPARAM2 gayle2_wput (uaecptr addr, uae_u32 value)
616: {
617: #ifdef JIT
618: special_mem |= S_WRITE;
619: #endif
620: gayle2_bput (addr, value >> 8);
621: gayle2_bput (addr + 1, value & 0xff);
622: }
623:
624: static void REGPARAM2 gayle2_bput (uaecptr addr, uae_u32 value)
625: {
626: #ifdef JIT
627: special_mem |= S_WRITE;
628: #endif
629: gayle2_write (addr, value);
630: }
631:
632: static uae_u8 ramsey_config;
633: static int gary_coldboot, gary_toenb, gary_timeout;
634: static int garyidoffset;
635:
636: static void mbres_write (uaecptr addr, uae_u32 val, int size)
637: {
638: addr &= 0xffff;
639:
640: if (MBRES_LOG > 0)
641: write_log ("MBRES_WRITE %08X=%08X (%d) PC=%08X S=%d\n", addr, val, size, m68k_getpc (), regs.s);
642: if (regs.s) { /* CPU FC = supervisor only */
643: if (addr == 0x1002)
644: garyidoffset = -1;
645: if (addr == 0x03)
646: ramsey_config = val;
647: if (addr == 0x02)
648: gary_coldboot = (val & 0x80) ? 1 : 0;
649: if (addr == 0x01)
650: gary_toenb = (val & 0x80) ? 1 : 0;
651: if (addr == 0x00)
652: gary_timeout = (val & 0x80) ? 1 : 0;
653: } else {
654: custom_bank.wput (addr, val);
655: }
656: }
657:
658: static uae_u32 mbres_read (uaecptr addr, int size)
659: {
660: uae_u32 v = 0;
661: addr &= 0xffff;
662:
663: if (regs.s) { /* CPU FC = supervisor only */
664: /* Gary ID (I don't think this exists in real chips..) */
665: if (addr == 0x1002 && currprefs.cs_fatgaryrev >= 0) {
666: garyidoffset++;
667: garyidoffset &= 7;
668: v = (currprefs.cs_fatgaryrev << garyidoffset) & 0x80;
669: }
670: if (addr == 0x43) { /* RAMSEY revision */
671: if (currprefs.cs_ramseyrev >= 0)
672: v = currprefs.cs_ramseyrev;
673: }
674: if (addr == 0x03) { /* RAMSEY config */
675: if (currprefs.cs_ramseyrev >= 0)
676: v = ramsey_config;
677: }
678: if (addr == 0x02) { /* coldreboot flag */
679: if (currprefs.cs_fatgaryrev >= 0)
680: v = gary_coldboot ? 0x80 : 0x00;
681: }
682: if (addr == 0x01) { /* toenb flag */
683: if (currprefs.cs_fatgaryrev >= 0)
684: v = gary_toenb ? 0x80 : 0x00;
685: }
686: if (addr == 0x00) { /* timeout flag */
687: if (currprefs.cs_fatgaryrev >= 0)
688: v = gary_timeout ? 0x80 : 0x00;
689: }
690: } else {
691: v = custom_bank.wget (addr);
692: }
693: if (MBRES_LOG > 0)
694: write_log ("MBRES_READ %08X=%08X (%d) PC=%08X S=%d\n", addr, v, size, m68k_getpc (), regs.s);
695: return v;
696: }
697:
698: static uae_u32 mbres_lget (uaecptr) REGPARAM;
699: static uae_u32 mbres_wget (uaecptr) REGPARAM;
700: static uae_u32 mbres_bget (uaecptr) REGPARAM;
701: static void mbres_lput (uaecptr, uae_u32) REGPARAM;
702: static void mbres_wput (uaecptr, uae_u32) REGPARAM;
703: static void mbres_bput (uaecptr, uae_u32) REGPARAM;
704:
705: static uae_u32 REGPARAM2 mbres_lget (uaecptr addr)
706: {
707: uae_u32 v;
708: #ifdef JIT
709: special_mem |= S_READ;
710: #endif
711: v = mbres_wget (addr) << 16;
712: v |= mbres_wget (addr + 2);
713: return v;
714: }
715: static uae_u32 REGPARAM2 mbres_wget (uaecptr addr)
716: {
717: #ifdef JIT
718: special_mem |= S_READ;
719: #endif
720: return mbres_read (addr, 2);
721: }
722: static uae_u32 REGPARAM2 mbres_bget (uaecptr addr)
723: {
724: #ifdef JIT
725: special_mem |= S_READ;
726: #endif
727: return mbres_read (addr, 1);
728: }
729:
730: static void REGPARAM2 mbres_lput (uaecptr addr, uae_u32 value)
731: {
732: #ifdef JIT
733: special_mem |= S_WRITE;
734: #endif
735: mbres_wput (addr, value >> 16);
736: mbres_wput (addr + 2, value & 0xffff);
737: }
738:
739: static void REGPARAM2 mbres_wput (uaecptr addr, uae_u32 value)
740: {
741: #ifdef JIT
742: special_mem |= S_WRITE;
743: #endif
744: mbres_write (addr, value, 2);
745: }
746:
747: static void REGPARAM2 mbres_bput (uaecptr addr, uae_u32 value)
748: {
749: #ifdef JIT
750: special_mem |= S_WRITE;
751: #endif
752: mbres_write (addr, value, 1);
753: }
754:
755: addrbank mbres_bank = {
756: mbres_lget, mbres_wget, mbres_bget,
757: mbres_lput, mbres_wput, mbres_bput,
758: default_xlate, default_check, NULL, "Motherboard Resources"
759: };
760:
761: void gayle_hsync (void)
762: {
763: int i;
764:
765: for (i = 0; i < 4; i++) {
766: struct ide_hdf *ide = &idedrive[i];
767: if (ide->irq_delay > 0) {
768: ide->irq_delay--;
769: if (ide->irq_delay == 0)
770: ide_interrupt_do (ide);
771: }
772: }
773: }
774:
775: static uae_u32 gayle_attr_read (uaecptr addr)
776: {
777: uae_u8 v = 0;
778: write_log ("R: %x %x\n", addr, m68k_getpc ());
779: addr &= 262144 - 1;
780: switch (addr)
781: {
782: case 0:
783: v = 0x91;
784: break;
785: case 2:
786: v = 0x05;
787: break;
788: case 4:
789: v = 0x23;
790: break;
791: }
792: return v;
793: }
794: static void gayle_attr_write (uaecptr addr, uae_u32 v)
795: {
796: write_log ("W: %x=%x %x\n", addr, v, m68k_getpc ());
797: addr &= 262144 - 1;
798: if (addr == 0x40000) {
799: if (v)
800: write_log ("GAYLE: Reset active\n");
801: else
802: write_log ("GAYLE: Reset non-active\n");
803: }
804: }
805:
806: static uae_u32 gayle_attr_lget (uaecptr) REGPARAM;
807: static uae_u32 gayle_attr_wget (uaecptr) REGPARAM;
808: static uae_u32 gayle_attr_bget (uaecptr) REGPARAM;
809: static void gayle_attr_lput (uaecptr, uae_u32) REGPARAM;
810: static void gayle_attr_wput (uaecptr, uae_u32) REGPARAM;
811: static void gayle_attr_bput (uaecptr, uae_u32) REGPARAM;
812:
813: addrbank gayle_attr_bank = {
814: gayle_attr_lget, gayle_attr_wget, gayle_attr_bget,
815: gayle_attr_lput, gayle_attr_wput, gayle_attr_bput,
816: default_xlate, default_check, NULL, "Gayle PCMCIA attribute"
817: };
818:
819: static uae_u32 REGPARAM2 gayle_attr_lget (uaecptr addr)
820: {
821: uae_u32 v;
822: #ifdef JIT
823: special_mem |= S_READ;
824: #endif
825: v = gayle_attr_wget (addr) << 16;
826: v |= gayle_attr_wget (addr + 2);
827: return v;
828: }
829: static uae_u32 REGPARAM2 gayle_attr_wget (uaecptr addr)
830: {
831: uae_u16 v;
832: #ifdef JIT
833: special_mem |= S_READ;
834: #endif
835: v = gayle_attr_bget (addr) << 8;
836: v |= gayle_attr_bget (addr + 1);
837: return v;
838: }
839: static uae_u32 REGPARAM2 gayle_attr_bget (uaecptr addr)
840: {
841: #ifdef JIT
842: special_mem |= S_READ;
843: #endif
844: return gayle_attr_read (addr);
845: }
846:
847: static void REGPARAM2 gayle_attr_lput (uaecptr addr, uae_u32 value)
848: {
849: #ifdef JIT
850: special_mem |= S_WRITE;
851: #endif
852: gayle_attr_wput (addr, value >> 16);
853: gayle_attr_wput (addr + 2, value & 0xffff);
854: }
855:
856: static void REGPARAM2 gayle_attr_wput (uaecptr addr, uae_u32 value)
857: {
858: #ifdef JIT
859: special_mem |= S_WRITE;
860: #endif
861: gayle_attr_bput (addr, value >> 8);
862: gayle_attr_bput (addr + 1, value & 0xff);
863: }
864:
865: static void REGPARAM2 gayle_attr_bput (uaecptr addr, uae_u32 value)
866: {
867: #ifdef JIT
868: special_mem |= S_WRITE;
869: #endif
870: gayle_attr_write (addr, value);
871: }
872:
873: static void initide (void)
874: {
875: int i;
876:
877: if (savestate_state == STATE_RESTORE)
878: return;
879: ide_error = 1;
880: ide_sector = ide_nsector = 1;
881: ide_select = 0;
882: ide_lcyl = ide_hcyl = ide_devcon = ide_feat = 0;
883: ide_drv = 0;
884: ide_splitter = 0;
885: gayle_irq = gayle_intena = 0;
886: if (currprefs.cs_ide == 2)
887: gayle_intena = 0xff;
888:
889: }
890:
891: void gayle_reset (int hardreset)
892: {
893: static char bankname[100];
894: initide ();
895: if (hardreset) {
896: ramsey_config = 0;
897: gary_coldboot = 1;
898: gary_timeout = 0;
899: gary_toenb = 0;
900: }
901: strcpy (bankname, "Gayle (low)");
902: if (currprefs.cs_ide == 2)
903: strcpy (bankname, "A4000 IDE");
904: #if 0
905: if (currprefs.cs_mbdmac == 2) {
906: strcat (bankname," + NCR53C710 SCSI");
907: ncr_reset ();
908: }
909: #endif
910: gayle_bank.name = bankname;
911: }
912:
913: const uae_u8 *restore_gayle (const uae_u8 *src)
914: {
915: changed_prefs.cs_ide = restore_u8();
916: gayle_intena = restore_u8();
917: gayle_irq = restore_u8();
918: ide_error = 0;
919: return src;
920: }
921:
922: uae_u8 *save_gayle (int *len)
923: {
924: uae_u8 *dstbak, *dst;
925:
926: if (currprefs.cs_ide <= 0)
927: return NULL;
928: dstbak = dst = (uae_u8*)malloc (1000);
929: save_u8 (currprefs.cs_ide);
930: save_u8 (gayle_intena);
931: save_u8 (gayle_irq);
932: *len = dst - dstbak;
933: return dstbak;
934: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.