1/*
2 *  linux/arch/m68k/atari/config.c
3 *
4 *  Copyright (C) 1994 Bjoern Brauel
5 *
6 *  5/2/94 Roman Hodek:
7 *    Added setting of time_adj to get a better clock.
8 *
9 *  5/14/94 Roman Hodek:
10 *    gettod() for TT
11 *
12 *  5/15/94 Roman Hodek:
13 *    hard_reset_now() for Atari (and others?)
14 *
15 *  94/12/30 Andreas Schwab:
16 *    atari_sched_init fixed to get precise clock.
17 *
18 * This file is subject to the terms and conditions of the GNU General Public
19 * License.  See the file COPYING in the main directory of this archive
20 * for more details.
21 */
22
23/*
24 * Miscellaneous atari stuff
25 */
26
27#include <linux/types.h>
28#include <linux/mm.h>
29#include <linux/console.h>
30#include <linux/init.h>
31#include <linux/delay.h>
32#include <linux/ioport.h>
33#include <linux/vt_kern.h>
34
35#include <asm/bootinfo.h>
36#include <asm/setup.h>
37#include <asm/atarihw.h>
38#include <asm/atariints.h>
39#include <asm/atari_stram.h>
40#include <asm/system.h>
41#include <asm/machdep.h>
42#include <asm/hwtest.h>
43#include <asm/io.h>
44
45u_long atari_mch_cookie;
46u_long atari_mch_type;
47struct atari_hw_present atari_hw_present;
48u_long atari_switches;
49int atari_dont_touch_floppy_select;
50int atari_rtc_year_offset;
51
52/* local function prototypes */
53static void atari_reset(void);
54static void atari_get_model(char *model);
55static int atari_get_hardware_list(char *buffer);
56
57/* atari specific irq functions */
58extern void atari_init_IRQ (void);
59extern void atari_mksound(unsigned int count, unsigned int ticks);
60#ifdef CONFIG_HEARTBEAT
61static void atari_heartbeat(int on);
62#endif
63
64/* atari specific timer functions (in time.c) */
65extern void atari_sched_init(irq_handler_t);
66extern unsigned long atari_gettimeoffset (void);
67extern int atari_mste_hwclk (int, struct rtc_time *);
68extern int atari_tt_hwclk (int, struct rtc_time *);
69extern int atari_mste_set_clock_mmss (unsigned long);
70extern int atari_tt_set_clock_mmss (unsigned long);
71
72
73/* ++roman: This is a more elaborate test for an SCC chip, since the plain
74 * Medusa board generates DTACK at the SCC's standard addresses, but a SCC
75 * board in the Medusa is possible. Also, the addresses where the ST_ESCC
76 * resides generate DTACK without the chip, too.
77 * The method is to write values into the interrupt vector register, that
78 * should be readable without trouble (from channel A!).
79 */
80
81static int __init scc_test(volatile char *ctla)
82{
83	if (!hwreg_present(ctla))
84		return 0;
85	MFPDELAY();
86
87	*ctla = 2;
88	MFPDELAY();
89	*ctla = 0x40;
90	MFPDELAY();
91
92	*ctla = 2;
93	MFPDELAY();
94	if (*ctla != 0x40)
95		return 0;
96	MFPDELAY();
97
98	*ctla = 2;
99	MFPDELAY();
100	*ctla = 0x60;
101	MFPDELAY();
102
103	*ctla = 2;
104	MFPDELAY();
105	if (*ctla != 0x60)
106		return 0;
107
108	return 1;
109}
110
111
112    /*
113     *  Parse an Atari-specific record in the bootinfo
114     */
115
116int __init atari_parse_bootinfo(const struct bi_record *record)
117{
118	int unknown = 0;
119	const u_long *data = record->data;
120
121	switch (record->tag) {
122	case BI_ATARI_MCH_COOKIE:
123		atari_mch_cookie = *data;
124		break;
125	case BI_ATARI_MCH_TYPE:
126		atari_mch_type = *data;
127		break;
128	default:
129		unknown = 1;
130		break;
131	}
132	return unknown;
133}
134
135
136/* Parse the Atari-specific switches= option. */
137static int __init atari_switches_setup(char *str)
138{
139	char switches[strlen(str) + 1];
140	char *p;
141	int ovsc_shift;
142	char *args = switches;
143
144	if (!MACH_IS_ATARI)
145		return 0;
146
147	/* copy string to local array, strsep works destructively... */
148	strcpy(switches, str);
149	atari_switches = 0;
150
151	/* parse the options */
152	while ((p = strsep(&args, ",")) != NULL) {
153		if (!*p)
154			continue;
155		ovsc_shift = 0;
156		if (strncmp(p, "ov_", 3) == 0) {
157			p += 3;
158			ovsc_shift = ATARI_SWITCH_OVSC_SHIFT;
159		}
160
161		if (strcmp(p, "ikbd") == 0) {
162			/* RTS line of IKBD ACIA */
163			atari_switches |= ATARI_SWITCH_IKBD << ovsc_shift;
164		} else if (strcmp(p, "midi") == 0) {
165			/* RTS line of MIDI ACIA */
166			atari_switches |= ATARI_SWITCH_MIDI << ovsc_shift;
167		} else if (strcmp(p, "snd6") == 0) {
168			atari_switches |= ATARI_SWITCH_SND6 << ovsc_shift;
169		} else if (strcmp(p, "snd7") == 0) {
170			atari_switches |= ATARI_SWITCH_SND7 << ovsc_shift;
171		}
172	}
173	return 0;
174}
175
176early_param("switches", atari_switches_setup);
177
178
179    /*
180     *  Setup the Atari configuration info
181     */
182
183void __init config_atari(void)
184{
185	unsigned short tos_version;
186
187	memset(&atari_hw_present, 0, sizeof(atari_hw_present));
188
189	/* Change size of I/O space from 64KB to 4GB. */
190	ioport_resource.end  = 0xFFFFFFFF;
191
192	mach_sched_init      = atari_sched_init;
193	mach_init_IRQ        = atari_init_IRQ;
194	mach_get_model	 = atari_get_model;
195	mach_get_hardware_list = atari_get_hardware_list;
196	mach_gettimeoffset   = atari_gettimeoffset;
197	mach_reset           = atari_reset;
198	mach_max_dma_address = 0xffffff;
199#if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE)
200	mach_beep          = atari_mksound;
201#endif
202#ifdef CONFIG_HEARTBEAT
203	mach_heartbeat = atari_heartbeat;
204#endif
205
206	/* Set switches as requested by the user */
207	if (atari_switches & ATARI_SWITCH_IKBD)
208		acia.key_ctrl = ACIA_DIV64 | ACIA_D8N1S | ACIA_RHTID;
209	if (atari_switches & ATARI_SWITCH_MIDI)
210		acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S | ACIA_RHTID;
211	if (atari_switches & (ATARI_SWITCH_SND6|ATARI_SWITCH_SND7)) {
212		sound_ym.rd_data_reg_sel = 14;
213		sound_ym.wd_data = sound_ym.rd_data_reg_sel |
214				   ((atari_switches&ATARI_SWITCH_SND6) ? 0x40 : 0) |
215				   ((atari_switches&ATARI_SWITCH_SND7) ? 0x80 : 0);
216	}
217
218	/* ++bjoern:
219	 * Determine hardware present
220	 */
221
222	printk("Atari hardware found: ");
223	if (MACH_IS_MEDUSA || MACH_IS_HADES) {
224		/* There's no Atari video hardware on the Medusa, but all the
225		 * addresses below generate a DTACK so no bus error occurs! */
226	} else if (hwreg_present(f030_xreg)) {
227		ATARIHW_SET(VIDEL_SHIFTER);
228		printk("VIDEL ");
229		/* This is a temporary hack: If there is Falcon video
230		 * hardware, we assume that the ST-DMA serves SCSI instead of
231		 * ACSI. In the future, there should be a better method for
232		 * this...
233		 */
234		ATARIHW_SET(ST_SCSI);
235		printk("STDMA-SCSI ");
236	} else if (hwreg_present(tt_palette)) {
237		ATARIHW_SET(TT_SHIFTER);
238		printk("TT_SHIFTER ");
239	} else if (hwreg_present(&shifter.bas_hi)) {
240		if (hwreg_present(&shifter.bas_lo) &&
241		    (shifter.bas_lo = 0x0aau, shifter.bas_lo == 0x0aau)) {
242			ATARIHW_SET(EXTD_SHIFTER);
243			printk("EXTD_SHIFTER ");
244		} else {
245			ATARIHW_SET(STND_SHIFTER);
246			printk("STND_SHIFTER ");
247		}
248	}
249	if (hwreg_present(&mfp.par_dt_reg)) {
250		ATARIHW_SET(ST_MFP);
251		printk("ST_MFP ");
252	}
253	if (hwreg_present(&tt_mfp.par_dt_reg)) {
254		ATARIHW_SET(TT_MFP);
255		printk("TT_MFP ");
256	}
257	if (hwreg_present(&tt_scsi_dma.dma_addr_hi)) {
258		ATARIHW_SET(SCSI_DMA);
259		printk("TT_SCSI_DMA ");
260	}
261	if (!MACH_IS_HADES && hwreg_present(&st_dma.dma_hi)) {
262		ATARIHW_SET(STND_DMA);
263		printk("STND_DMA ");
264	}
265	/*
266	 * The ST-DMA address registers aren't readable
267	 * on all Medusas, so the test below may fail
268	 */
269	if (MACH_IS_MEDUSA ||
270	    (hwreg_present(&st_dma.dma_vhi) &&
271	     (st_dma.dma_vhi = 0x55) && (st_dma.dma_hi = 0xaa) &&
272	     st_dma.dma_vhi == 0x55 && st_dma.dma_hi == 0xaa &&
273	     (st_dma.dma_vhi = 0xaa) && (st_dma.dma_hi = 0x55) &&
274	     st_dma.dma_vhi == 0xaa && st_dma.dma_hi == 0x55)) {
275		ATARIHW_SET(EXTD_DMA);
276		printk("EXTD_DMA ");
277	}
278	if (hwreg_present(&tt_scsi.scsi_data)) {
279		ATARIHW_SET(TT_SCSI);
280		printk("TT_SCSI ");
281	}
282	if (hwreg_present(&sound_ym.rd_data_reg_sel)) {
283		ATARIHW_SET(YM_2149);
284		printk("YM2149 ");
285	}
286	if (!MACH_IS_MEDUSA && !MACH_IS_HADES &&
287		hwreg_present(&tt_dmasnd.ctrl)) {
288		ATARIHW_SET(PCM_8BIT);
289		printk("PCM ");
290	}
291	if (!MACH_IS_HADES && hwreg_present(&falcon_codec.unused5)) {
292		ATARIHW_SET(CODEC);
293		printk("CODEC ");
294	}
295	if (hwreg_present(&dsp56k_host_interface.icr)) {
296		ATARIHW_SET(DSP56K);
297		printk("DSP56K ");
298	}
299	if (hwreg_present(&tt_scc_dma.dma_ctrl) &&
300	    !MACH_IS_MEDUSA && !MACH_IS_HADES
301	    ) {
302		ATARIHW_SET(SCC_DMA);
303		printk("SCC_DMA ");
304	}
305	if (scc_test(&scc.cha_a_ctrl)) {
306		ATARIHW_SET(SCC);
307		printk("SCC ");
308	}
309	if (scc_test(&st_escc.cha_b_ctrl)) {
310		ATARIHW_SET(ST_ESCC);
311		printk("ST_ESCC ");
312	}
313	if (MACH_IS_HADES) {
314		ATARIHW_SET(VME);
315		printk("VME ");
316	} else if (hwreg_present(&tt_scu.sys_mask)) {
317		ATARIHW_SET(SCU);
318		/* Assume a VME bus if there's a SCU */
319		ATARIHW_SET(VME);
320		printk("VME SCU ");
321	}
322	if (hwreg_present((void *)(0xffff9210))) {
323		ATARIHW_SET(ANALOG_JOY);
324		printk("ANALOG_JOY ");
325	}
326	if (!MACH_IS_HADES && hwreg_present(blitter.halftone)) {
327		ATARIHW_SET(BLITTER);
328		printk("BLITTER ");
329	}
330	if (hwreg_present((void *)0xfff00039)) {
331		ATARIHW_SET(IDE);
332		printk("IDE ");
333	}
334	if (!MACH_IS_MEDUSA && !MACH_IS_HADES &&
335	    hwreg_present(&tt_microwire.data) &&
336	    hwreg_present(&tt_microwire.mask) &&
337	    (tt_microwire.mask = 0x7ff,
338	     udelay(1),
339	     tt_microwire.data = MW_LM1992_PSG_HIGH | MW_LM1992_ADDR,
340	     udelay(1),
341	     tt_microwire.data != 0)) {
342		ATARIHW_SET(MICROWIRE);
343		while (tt_microwire.mask != 0x7ff)
344			;
345		printk("MICROWIRE ");
346	}
347	if (hwreg_present(&tt_rtc.regsel)) {
348		ATARIHW_SET(TT_CLK);
349		printk("TT_CLK ");
350		mach_hwclk = atari_tt_hwclk;
351		mach_set_clock_mmss = atari_tt_set_clock_mmss;
352	}
353	if (!MACH_IS_HADES && hwreg_present(&mste_rtc.sec_ones)) {
354		ATARIHW_SET(MSTE_CLK);
355		printk("MSTE_CLK ");
356		mach_hwclk = atari_mste_hwclk;
357		mach_set_clock_mmss = atari_mste_set_clock_mmss;
358	}
359	if (!MACH_IS_MEDUSA && !MACH_IS_HADES &&
360	    hwreg_present(&dma_wd.fdc_speed) &&
361	    hwreg_write(&dma_wd.fdc_speed, 0)) {
362		ATARIHW_SET(FDCSPEED);
363		printk("FDC_SPEED ");
364	}
365	if (!MACH_IS_HADES && !ATARIHW_PRESENT(ST_SCSI)) {
366		ATARIHW_SET(ACSI);
367		printk("ACSI ");
368	}
369	printk("\n");
370
371	if (CPU_IS_040_OR_060)
372		/* Now it seems to be safe to turn of the tt0 transparent
373		 * translation (the one that must not be turned off in
374		 * head.S...)
375		 */
376		asm volatile ("\n"
377			"	moveq	#0,%%d0\n"
378			"	.chip	68040\n"
379			"	movec	%%d0,%%itt0\n"
380			"	movec	%%d0,%%dtt0\n"
381			"	.chip	68k"
382			: /* no outputs */
383			: /* no inputs */
384			: "d0");
385
386	/* allocator for memory that must reside in st-ram */
387	atari_stram_init();
388
389	/* Set up a mapping for the VMEbus address region:
390	 *
391	 * VME is either at phys. 0xfexxxxxx (TT) or 0xa00000..0xdfffff
392	 * (MegaSTE) In both cases, the whole 16 MB chunk is mapped at
393	 * 0xfe000000 virt., because this can be done with a single
394	 * transparent translation. On the 68040, lots of often unused
395	 * page tables would be needed otherwise. On a MegaSTE or similar,
396	 * the highest byte is stripped off by hardware due to the 24 bit
397	 * design of the bus.
398	 */
399
400	if (CPU_IS_020_OR_030) {
401		unsigned long tt1_val;
402		tt1_val = 0xfe008543;	/* Translate 0xfexxxxxx, enable, cache
403					 * inhibit, read and write, FDC mask = 3,
404					 * FDC val = 4 -> Supervisor only */
405		asm volatile ("\n"
406			"	.chip	68030\n"
407			"	pmove	%0@,%/tt1\n"
408			"	.chip	68k"
409			: : "a" (&tt1_val));
410	} else {
411	        asm volatile ("\n"
412			"	.chip	68040\n"
413			"	movec	%0,%%itt1\n"
414			"	movec	%0,%%dtt1\n"
415			"	.chip	68k"
416			:
417			: "d" (0xfe00a040));	/* Translate 0xfexxxxxx, enable,
418						 * supervisor only, non-cacheable/
419						 * serialized, writable */
420
421	}
422
423	/* Fetch tos version at Physical 2 */
424	/*
425	 * We my not be able to access this address if the kernel is
426	 * loaded to st ram, since the first page is unmapped.  On the
427	 * Medusa this is always the case and there is nothing we can do
428	 * about this, so we just assume the smaller offset.  For the TT
429	 * we use the fact that in head.S we have set up a mapping
430	 * 0xFFxxxxxx -> 0x00xxxxxx, so that the first 16MB is accessible
431	 * in the last 16MB of the address space.
432	 */
433	tos_version = (MACH_IS_MEDUSA || MACH_IS_HADES) ?
434			0xfff : *(unsigned short *)0xff000002;
435	atari_rtc_year_offset = (tos_version < 0x306) ? 70 : 68;
436}
437
438#ifdef CONFIG_HEARTBEAT
439static void atari_heartbeat(int on)
440{
441	unsigned char tmp;
442	unsigned long flags;
443
444	if (atari_dont_touch_floppy_select)
445		return;
446
447	local_irq_save(flags);
448	sound_ym.rd_data_reg_sel = 14;	/* Select PSG Port A */
449	tmp = sound_ym.rd_data_reg_sel;
450	sound_ym.wd_data = on ? (tmp & ~0x02) : (tmp | 0x02);
451	local_irq_restore(flags);
452}
453#endif
454
455/* ++roman:
456 *
457 * This function does a reset on machines that lack the ability to
458 * assert the processor's _RESET signal somehow via hardware. It is
459 * based on the fact that you can find the initial SP and PC values
460 * after a reset at physical addresses 0 and 4. This works pretty well
461 * for Atari machines, since the lowest 8 bytes of physical memory are
462 * really ROM (mapped by hardware). For other 680x0 machines: don't
463 * know if it works...
464 *
465 * To get the values at addresses 0 and 4, the MMU better is turned
466 * off first. After that, we have to jump into physical address space
467 * (the PC before the pmove statement points to the virtual address of
468 * the code). Getting that physical address is not hard, but the code
469 * becomes a bit complex since I've tried to ensure that the jump
470 * statement after the pmove is in the cache already (otherwise the
471 * processor can't fetch it!). For that, the code first jumps to the
472 * jump statement with the (virtual) address of the pmove section in
473 * an address register . The jump statement is surely in the cache
474 * now. After that, that physical address of the reset code is loaded
475 * into the same address register, pmove is done and the same jump
476 * statements goes to the reset code. Since there are not many
477 * statements between the two jumps, I hope it stays in the cache.
478 *
479 * The C code makes heavy use of the GCC features that you can get the
480 * address of a C label. No hope to compile this with another compiler
481 * than GCC!
482 */
483
484/* ++andreas: no need for complicated code, just depend on prefetch */
485
486static void atari_reset(void)
487{
488	long tc_val = 0;
489	long reset_addr;
490
491	/*
492	 * On the Medusa, phys. 0x4 may contain garbage because it's no
493	 * ROM.  See above for explanation why we cannot use PTOV(4).
494	 */
495	reset_addr = MACH_IS_HADES ? 0x7fe00030 :
496		     MACH_IS_MEDUSA || MACH_IS_AB40 ? 0xe00030 :
497		     *(unsigned long *) 0xff000004;
498
499	/* reset ACIA for switch off OverScan, if it's active */
500	if (atari_switches & ATARI_SWITCH_OVSC_IKBD)
501		acia.key_ctrl = ACIA_RESET;
502	if (atari_switches & ATARI_SWITCH_OVSC_MIDI)
503		acia.mid_ctrl = ACIA_RESET;
504
505	/* processor independent: turn off interrupts and reset the VBR;
506	 * the caches must be left enabled, else prefetching the final jump
507	 * instruction doesn't work.
508	 */
509	local_irq_disable();
510	asm volatile ("movec	%0,%%vbr"
511			: : "d" (0));
512
513	if (CPU_IS_040_OR_060) {
514		unsigned long jmp_addr040 = virt_to_phys(&&jmp_addr_label040);
515		if (CPU_IS_060) {
516			/* 68060: clear PCR to turn off superscalar operation */
517			asm volatile ("\n"
518				"	.chip 68060\n"
519				"	movec %0,%%pcr\n"
520				"	.chip 68k"
521				: : "d" (0));
522		}
523
524		asm volatile ("\n"
525			"	move.l	%0,%%d0\n"
526			"	and.l	#0xff000000,%%d0\n"
527			"	or.w	#0xe020,%%d0\n"   /* map 16 MB, enable, cacheable */
528			"	.chip	68040\n"
529			"	movec	%%d0,%%itt0\n"
530			"	movec	%%d0,%%dtt0\n"
531			"	.chip	68k\n"
532			"	jmp	%0@"
533			: : "a" (jmp_addr040)
534			: "d0");
535	jmp_addr_label040:
536		asm volatile ("\n"
537			"	moveq	#0,%%d0\n"
538			"	nop\n"
539			"	.chip	68040\n"
540			"	cinva	%%bc\n"
541			"	nop\n"
542			"	pflusha\n"
543			"	nop\n"
544			"	movec	%%d0,%%tc\n"
545			"	nop\n"
546			/* the following setup of transparent translations is needed on the
547			 * Afterburner040 to successfully reboot. Other machines shouldn't
548			 * care about a different tt regs setup, they also didn't care in
549			 * the past that the regs weren't turned off. */
550			"	move.l	#0xffc000,%%d0\n" /* whole insn space cacheable */
551			"	movec	%%d0,%%itt0\n"
552			"	movec	%%d0,%%itt1\n"
553			"	or.w	#0x40,%/d0\n" /* whole data space non-cacheable/ser. */
554			"	movec	%%d0,%%dtt0\n"
555			"	movec	%%d0,%%dtt1\n"
556			"	.chip	68k\n"
557			"	jmp	%0@"
558			: /* no outputs */
559			: "a" (reset_addr)
560			: "d0");
561	} else
562		asm volatile ("\n"
563			"	pmove	%0@,%%tc\n"
564			"	jmp	%1@"
565			: /* no outputs */
566			: "a" (&tc_val), "a" (reset_addr));
567}
568
569
570static void atari_get_model(char *model)
571{
572	strcpy(model, "Atari ");
573	switch (atari_mch_cookie >> 16) {
574	case ATARI_MCH_ST:
575		if (ATARIHW_PRESENT(MSTE_CLK))
576			strcat(model, "Mega ST");
577		else
578			strcat(model, "ST");
579		break;
580	case ATARI_MCH_STE:
581		if (MACH_IS_MSTE)
582			strcat(model, "Mega STE");
583		else
584			strcat(model, "STE");
585		break;
586	case ATARI_MCH_TT:
587		if (MACH_IS_MEDUSA)
588			/* Medusa has TT _MCH cookie */
589			strcat(model, "Medusa");
590		else if (MACH_IS_HADES)
591			strcat(model, "Hades");
592		else
593			strcat(model, "TT");
594		break;
595	case ATARI_MCH_FALCON:
596		strcat(model, "Falcon");
597		if (MACH_IS_AB40)
598			strcat(model, " (with Afterburner040)");
599		break;
600	default:
601		sprintf(model + strlen(model), "(unknown mach cookie 0x%lx)",
602			atari_mch_cookie);
603		break;
604	}
605}
606
607
608static int atari_get_hardware_list(char *buffer)
609{
610	int len = 0, i;
611
612	for (i = 0; i < m68k_num_memory; i++)
613		len += sprintf(buffer+len, "\t%3ld MB at 0x%08lx (%s)\n",
614				m68k_memory[i].size >> 20, m68k_memory[i].addr,
615				(m68k_memory[i].addr & 0xff000000 ?
616				 "alternate RAM" : "ST-RAM"));
617
618#define ATARIHW_ANNOUNCE(name, str)			\
619	if (ATARIHW_PRESENT(name))			\
620		len += sprintf(buffer + len, "\t%s\n", str)
621
622	len += sprintf(buffer + len, "Detected hardware:\n");
623	ATARIHW_ANNOUNCE(STND_SHIFTER, "ST Shifter");
624	ATARIHW_ANNOUNCE(EXTD_SHIFTER, "STe Shifter");
625	ATARIHW_ANNOUNCE(TT_SHIFTER, "TT Shifter");
626	ATARIHW_ANNOUNCE(VIDEL_SHIFTER, "Falcon Shifter");
627	ATARIHW_ANNOUNCE(YM_2149, "Programmable Sound Generator");
628	ATARIHW_ANNOUNCE(PCM_8BIT, "PCM 8 Bit Sound");
629	ATARIHW_ANNOUNCE(CODEC, "CODEC Sound");
630	ATARIHW_ANNOUNCE(TT_SCSI, "SCSI Controller NCR5380 (TT style)");
631	ATARIHW_ANNOUNCE(ST_SCSI, "SCSI Controller NCR5380 (Falcon style)");
632	ATARIHW_ANNOUNCE(ACSI, "ACSI Interface");
633	ATARIHW_ANNOUNCE(IDE, "IDE Interface");
634	ATARIHW_ANNOUNCE(FDCSPEED, "8/16 Mhz Switch for FDC");
635	ATARIHW_ANNOUNCE(ST_MFP, "Multi Function Peripheral MFP 68901");
636	ATARIHW_ANNOUNCE(TT_MFP, "Second Multi Function Peripheral MFP 68901");
637	ATARIHW_ANNOUNCE(SCC, "Serial Communications Controller SCC 8530");
638	ATARIHW_ANNOUNCE(ST_ESCC, "Extended Serial Communications Controller SCC 85230");
639	ATARIHW_ANNOUNCE(ANALOG_JOY, "Paddle Interface");
640	ATARIHW_ANNOUNCE(MICROWIRE, "MICROWIRE(tm) Interface");
641	ATARIHW_ANNOUNCE(STND_DMA, "DMA Controller (24 bit)");
642	ATARIHW_ANNOUNCE(EXTD_DMA, "DMA Controller (32 bit)");
643	ATARIHW_ANNOUNCE(SCSI_DMA, "DMA Controller for NCR5380");
644	ATARIHW_ANNOUNCE(SCC_DMA, "DMA Controller for SCC");
645	ATARIHW_ANNOUNCE(TT_CLK, "Clock Chip MC146818A");
646	ATARIHW_ANNOUNCE(MSTE_CLK, "Clock Chip RP5C15");
647	ATARIHW_ANNOUNCE(SCU, "System Control Unit");
648	ATARIHW_ANNOUNCE(BLITTER, "Blitter");
649	ATARIHW_ANNOUNCE(VME, "VME Bus");
650	ATARIHW_ANNOUNCE(DSP56K, "DSP56001 processor");
651
652	return len;
653}
654