2 * linux/arch/m68k/atari/config.c
4 * Copyright (C) 1994 Bjoern Brauel
7 * Added setting of time_adj to get a better clock.
12 * 5/15/94 Roman Hodek:
13 * hard_reset_now() for Atari (and others?)
15 * 94/12/30 Andreas Schwab:
16 * atari_sched_init fixed to get precise clock.
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
24 * Miscellaneous atari stuff
27 #include <linux/config.h>
28 #include <linux/types.h>
30 #include <linux/console.h>
31 #include <linux/init.h>
32 #include <linux/delay.h>
33 #include <linux/ioport.h>
34 #include <linux/vt_kern.h>
36 #include <asm/bootinfo.h>
37 #include <asm/setup.h>
38 #include <asm/atarihw.h>
39 #include <asm/atariints.h>
40 #include <asm/atari_stram.h>
41 #include <asm/system.h>
42 #include <asm/keyboard.h>
43 #include <asm/machdep.h>
44 #include <asm/hwtest.h>
47 u_long atari_mch_cookie;
48 u_long atari_mch_type = 0;
49 struct atari_hw_present atari_hw_present;
50 u_long atari_switches = 0;
51 int atari_dont_touch_floppy_select = 0;
52 int atari_rtc_year_offset;
54 /* local function prototypes */
55 static void atari_reset( void );
56 #ifdef CONFIG_ATARI_FLOPPY
57 extern void atari_floppy_setup(char *, int *);
59 static void atari_get_model(char *model);
60 static int atari_get_hardware_list(char *buffer);
62 /* atari specific keyboard functions */
63 extern int atari_keyb_init(void);
64 extern int atari_kbdrate (struct kbd_repeat *);
65 extern int atari_kbd_translate(unsigned char keycode, unsigned char *keycodep,
67 extern void atari_kbd_leds (unsigned int);
68 /* atari specific irq functions */
69 extern void atari_init_IRQ (void);
70 extern int atari_request_irq (unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
71 unsigned long flags, const char *devname, void *dev_id);
72 extern void atari_free_irq (unsigned int irq, void *dev_id);
73 extern void atari_enable_irq (unsigned int);
74 extern void atari_disable_irq (unsigned int);
75 extern int atari_get_irq_list (char *buf);
76 extern void atari_mksound( unsigned int count, unsigned int ticks );
77 #ifdef CONFIG_HEARTBEAT
78 static void atari_heartbeat( int on );
81 /* atari specific timer functions (in time.c) */
82 extern void atari_sched_init(void (*)(int, void *, struct pt_regs *));
83 extern unsigned long atari_gettimeoffset (void);
84 extern void atari_mste_gettod (int *, int *, int *, int *, int *, int *);
85 extern void atari_tt_gettod (int *, int *, int *, int *, int *, int *);
86 extern int atari_mste_hwclk (int, struct rtc_time *);
87 extern int atari_tt_hwclk (int, struct rtc_time *);
88 extern int atari_mste_set_clock_mmss (unsigned long);
89 extern int atari_tt_set_clock_mmss (unsigned long);
91 /* atari specific debug functions (in debug.c) */
92 extern void atari_debug_init(void);
94 #ifdef CONFIG_MAGIC_SYSRQ
95 static char atari_sysrq_xlate[128] =
96 "\000\0331234567890-=\177\t" /* 0x00 - 0x0f */
97 "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */
98 "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */
99 "bnm,./\000\000\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */
100 "\206\207\210\211\212\000\000\000\000\000-\000\000\000+\000"/* 0x40 - 0x4f */
101 "\000\000\000\177\000\000\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
102 "\000\000\000()/*789456123" /* 0x60 - 0x6f */
103 "0.\r\000\000\000\000\000\000\000\000\000\000\000\000\000"; /* 0x70 - 0x7f */
107 /* I've moved hwreg_present() and hwreg_present_bywrite() out into
108 * mm/hwtest.c, to avoid having multiple copies of the same routine
109 * in the kernel [I wanted them in hp300 and they were already used
110 * in the nubus code. NB: I don't have an Atari so this might (just
111 * conceivably) break something.
112 * I've preserved the #if 0 version of hwreg_present_bywrite() here
114 * -- Peter Maydell <pmaydell@chiark.greenend.org.uk>, 05/1998
119 hwreg_present_bywrite(volatile void *regp, unsigned char val)
122 long save_sp, save_vbr;
123 static long tmp_vectors[3] = { 0, 0, (long)&&after_test };
126 ( "movec %/vbr,%2\n\t" /* save vbr value */
127 "movec %4,%/vbr\n\t" /* set up temporary vectors */
128 "movel %/sp,%1\n\t" /* save sp */
129 "moveq #0,%0\n\t" /* assume not present */
130 "moveb %5,%3@\n\t" /* write the hardware reg */
131 "cmpb %3@,%5\n\t" /* compare it */
132 "seq %0" /* comes here only if reg */
134 : "=d&" (ret), "=r&" (save_sp), "=r&" (save_vbr)
135 : "a" (regp), "r" (tmp_vectors), "d" (val)
139 ( "movel %0,%/sp\n\t" /* restore sp */
140 "movec %1,%/vbr" /* restore vbr */
141 : : "r" (save_sp), "r" (save_vbr) : "sp"
149 /* ++roman: This is a more elaborate test for an SCC chip, since the plain
150 * Medusa board generates DTACK at the SCC's standard addresses, but a SCC
151 * board in the Medusa is possible. Also, the addresses where the ST_ESCC
152 * resides generate DTACK without the chip, too.
153 * The method is to write values into the interrupt vector register, that
154 * should be readable without trouble (from channel A!).
157 static int __init scc_test( volatile char *ctla )
159 if (!hwreg_present( ctla ))
163 *ctla = 2; MFPDELAY();
164 *ctla = 0x40; MFPDELAY();
166 *ctla = 2; MFPDELAY();
167 if (*ctla != 0x40) return( 0 );
170 *ctla = 2; MFPDELAY();
171 *ctla = 0x60; MFPDELAY();
173 *ctla = 2; MFPDELAY();
174 if (*ctla != 0x60) return( 0 );
181 * Parse an Atari-specific record in the bootinfo
184 int __init atari_parse_bootinfo(const struct bi_record *record)
187 const u_long *data = record->data;
189 switch (record->tag) {
190 case BI_ATARI_MCH_COOKIE:
191 atari_mch_cookie = *data;
193 case BI_ATARI_MCH_TYPE:
194 atari_mch_type = *data;
203 /* Parse the Atari-specific switches= option. */
204 void __init atari_switches_setup( const char *str, unsigned len )
206 char switches[len+1];
210 /* copy string to local array, strtok works destructively... */
211 strncpy( switches, str, len );
215 /* parse the options */
216 for( p = strtok( switches, "," ); p; p = strtok( NULL, "," ) ) {
218 if (strncmp( p, "ov_", 3 ) == 0) {
220 ovsc_shift = ATARI_SWITCH_OVSC_SHIFT;
223 if (strcmp( p, "ikbd" ) == 0) {
224 /* RTS line of IKBD ACIA */
225 atari_switches |= ATARI_SWITCH_IKBD << ovsc_shift;
227 else if (strcmp( p, "midi" ) == 0) {
228 /* RTS line of MIDI ACIA */
229 atari_switches |= ATARI_SWITCH_MIDI << ovsc_shift;
231 else if (strcmp( p, "snd6" ) == 0) {
232 atari_switches |= ATARI_SWITCH_SND6 << ovsc_shift;
234 else if (strcmp( p, "snd7" ) == 0) {
235 atari_switches |= ATARI_SWITCH_SND7 << ovsc_shift;
242 * Setup the Atari configuration info
245 void __init config_atari(void)
247 unsigned short tos_version;
249 memset(&atari_hw_present, 0, sizeof(atari_hw_present));
253 ioport_resource.end = 0xFFFFFFFF; /* Change size of I/O space from 64KB
256 mach_sched_init = atari_sched_init;
258 mach_keyb_init = atari_keyb_init;
259 mach_kbdrate = atari_kbdrate;
260 mach_kbd_translate = atari_kbd_translate;
261 mach_kbd_leds = atari_kbd_leds;
262 kd_mksound = atari_mksound;
264 mach_init_IRQ = atari_init_IRQ;
265 mach_request_irq = atari_request_irq;
266 mach_free_irq = atari_free_irq;
267 enable_irq = atari_enable_irq;
268 disable_irq = atari_disable_irq;
269 mach_get_model = atari_get_model;
270 mach_get_hardware_list = atari_get_hardware_list;
271 mach_get_irq_list = atari_get_irq_list;
272 mach_gettimeoffset = atari_gettimeoffset;
273 mach_reset = atari_reset;
274 #ifdef CONFIG_ATARI_FLOPPY
275 mach_floppy_setup = atari_floppy_setup;
277 #ifdef CONFIG_DUMMY_CONSOLE
278 conswitchp = &dummy_con;
280 mach_max_dma_address = 0xffffff;
281 #ifdef CONFIG_MAGIC_SYSRQ
283 mach_sysrq_key = 98; /* HELP */
284 mach_sysrq_shift_state = 8; /* Alt */
285 mach_sysrq_shift_mask = 0xff; /* all modifiers except CapsLock */
286 mach_sysrq_xlate = atari_sysrq_xlate;
288 #ifdef CONFIG_HEARTBEAT
289 mach_heartbeat = atari_heartbeat;
292 /* Set switches as requested by the user */
293 if (atari_switches & ATARI_SWITCH_IKBD)
294 acia.key_ctrl = ACIA_DIV64 | ACIA_D8N1S | ACIA_RHTID;
295 if (atari_switches & ATARI_SWITCH_MIDI)
296 acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S | ACIA_RHTID;
297 if (atari_switches & (ATARI_SWITCH_SND6|ATARI_SWITCH_SND7)) {
298 sound_ym.rd_data_reg_sel = 14;
299 sound_ym.wd_data = sound_ym.rd_data_reg_sel |
300 ((atari_switches&ATARI_SWITCH_SND6) ? 0x40 : 0) |
301 ((atari_switches&ATARI_SWITCH_SND7) ? 0x80 : 0);
305 * Determine hardware present
308 printk( "Atari hardware found: " );
309 if (MACH_IS_MEDUSA || MACH_IS_HADES) {
310 /* There's no Atari video hardware on the Medusa, but all the
311 * addresses below generate a DTACK so no bus error occurs! */
313 else if (hwreg_present( f030_xreg )) {
314 ATARIHW_SET(VIDEL_SHIFTER);
316 /* This is a temporary hack: If there is Falcon video
317 * hardware, we assume that the ST-DMA serves SCSI instead of
318 * ACSI. In the future, there should be a better method for
321 ATARIHW_SET(ST_SCSI);
322 printk( "STDMA-SCSI " );
324 else if (hwreg_present( tt_palette )) {
325 ATARIHW_SET(TT_SHIFTER);
326 printk( "TT_SHIFTER " );
328 else if (hwreg_present( &shifter.bas_hi )) {
329 if (hwreg_present( &shifter.bas_lo ) &&
330 (shifter.bas_lo = 0x0aau, shifter.bas_lo == 0x0aau)) {
331 ATARIHW_SET(EXTD_SHIFTER);
332 printk( "EXTD_SHIFTER " );
335 ATARIHW_SET(STND_SHIFTER);
336 printk( "STND_SHIFTER " );
339 if (hwreg_present( &mfp.par_dt_reg )) {
343 if (hwreg_present( &tt_mfp.par_dt_reg )) {
347 if (hwreg_present( &tt_scsi_dma.dma_addr_hi )) {
348 ATARIHW_SET(SCSI_DMA);
349 printk( "TT_SCSI_DMA " );
351 if (!MACH_IS_HADES && hwreg_present( &st_dma.dma_hi )) {
352 ATARIHW_SET(STND_DMA);
353 printk( "STND_DMA " );
355 if (MACH_IS_MEDUSA || /* The ST-DMA address registers aren't readable
356 * on all Medusas, so the test below may fail */
357 (hwreg_present( &st_dma.dma_vhi ) &&
358 (st_dma.dma_vhi = 0x55) && (st_dma.dma_hi = 0xaa) &&
359 st_dma.dma_vhi == 0x55 && st_dma.dma_hi == 0xaa &&
360 (st_dma.dma_vhi = 0xaa) && (st_dma.dma_hi = 0x55) &&
361 st_dma.dma_vhi == 0xaa && st_dma.dma_hi == 0x55)) {
362 ATARIHW_SET(EXTD_DMA);
363 printk( "EXTD_DMA " );
365 if (hwreg_present( &tt_scsi.scsi_data )) {
366 ATARIHW_SET(TT_SCSI);
367 printk( "TT_SCSI " );
369 if (hwreg_present( &sound_ym.rd_data_reg_sel )) {
370 ATARIHW_SET(YM_2149);
373 if (!MACH_IS_MEDUSA && !MACH_IS_HADES &&
374 hwreg_present( &tt_dmasnd.ctrl )) {
375 ATARIHW_SET(PCM_8BIT);
378 if (!MACH_IS_HADES && hwreg_present( &codec.unused5 )) {
382 if (hwreg_present( &dsp56k_host_interface.icr )) {
386 if (hwreg_present( &tt_scc_dma.dma_ctrl ) &&
388 /* This test sucks! Who knows some better? */
389 (tt_scc_dma.dma_ctrl = 0x01, (tt_scc_dma.dma_ctrl & 1) == 1) &&
390 (tt_scc_dma.dma_ctrl = 0x00, (tt_scc_dma.dma_ctrl & 1) == 0)
392 !MACH_IS_MEDUSA && !MACH_IS_HADES
395 ATARIHW_SET(SCC_DMA);
396 printk( "SCC_DMA " );
398 if (scc_test( &scc.cha_a_ctrl )) {
402 if (scc_test( &st_escc.cha_b_ctrl )) {
403 ATARIHW_SET( ST_ESCC );
404 printk( "ST_ESCC " );
411 else if (hwreg_present( &tt_scu.sys_mask )) {
413 /* Assume a VME bus if there's a SCU */
415 printk( "VME SCU " );
417 if (hwreg_present( (void *)(0xffff9210) )) {
418 ATARIHW_SET(ANALOG_JOY);
419 printk( "ANALOG_JOY " );
421 if (!MACH_IS_HADES && hwreg_present( blitter.halftone )) {
422 ATARIHW_SET(BLITTER);
423 printk( "BLITTER " );
425 if (hwreg_present((void *)0xfff00039)) {
429 #if 1 /* This maybe wrong */
430 if (!MACH_IS_MEDUSA && !MACH_IS_HADES &&
431 hwreg_present( &tt_microwire.data ) &&
432 hwreg_present( &tt_microwire.mask ) &&
433 (tt_microwire.mask = 0x7ff,
435 tt_microwire.data = MW_LM1992_PSG_HIGH | MW_LM1992_ADDR,
437 tt_microwire.data != 0)) {
438 ATARIHW_SET(MICROWIRE);
439 while (tt_microwire.mask != 0x7ff) ;
440 printk( "MICROWIRE " );
443 if (hwreg_present( &tt_rtc.regsel )) {
446 mach_gettod = atari_tt_gettod;
447 mach_hwclk = atari_tt_hwclk;
448 mach_set_clock_mmss = atari_tt_set_clock_mmss;
450 if (!MACH_IS_HADES && hwreg_present( &mste_rtc.sec_ones)) {
451 ATARIHW_SET(MSTE_CLK);
452 printk( "MSTE_CLK ");
453 mach_gettod = atari_mste_gettod;
454 mach_hwclk = atari_mste_hwclk;
455 mach_set_clock_mmss = atari_mste_set_clock_mmss;
457 if (!MACH_IS_MEDUSA && !MACH_IS_HADES &&
458 hwreg_present( &dma_wd.fdc_speed ) &&
459 hwreg_write( &dma_wd.fdc_speed, 0 )) {
460 ATARIHW_SET(FDCSPEED);
461 printk( "FDC_SPEED ");
463 if (!MACH_IS_HADES && !ATARIHW_PRESENT(ST_SCSI)) {
469 if (CPU_IS_040_OR_060)
470 /* Now it seems to be safe to turn of the tt0 transparent
471 * translation (the one that must not be turned off in
474 __asm__ volatile ("moveq #0,%/d0\n\t"
476 "movec %%d0,%%itt0\n\t"
477 "movec %%d0,%%dtt0\n\t"
483 /* allocator for memory that must reside in st-ram */
486 /* Set up a mapping for the VMEbus address region:
488 * VME is either at phys. 0xfexxxxxx (TT) or 0xa00000..0xdfffff
489 * (MegaSTE) In both cases, the whole 16 MB chunk is mapped at
490 * 0xfe000000 virt., because this can be done with a single
491 * transparent translation. On the 68040, lots of often unused
492 * page tables would be needed otherwise. On a MegaSTE or similar,
493 * the highest byte is stripped off by hardware due to the 24 bit
497 if (CPU_IS_020_OR_030) {
498 unsigned long tt1_val;
499 tt1_val = 0xfe008543; /* Translate 0xfexxxxxx, enable, cache
500 * inhibit, read and write, FDC mask = 3,
501 * FDC val = 4 -> Supervisor only */
502 __asm__ __volatile__ ( ".chip 68030\n\t"
503 "pmove %0@,%/tt1\n\t"
505 : : "a" (&tt1_val) );
509 ( "movel %0,%/d0\n\t"
511 "movec %%d0,%%itt1\n\t"
512 "movec %%d0,%%dtt1\n\t"
515 : "g" (0xfe00a040) /* Translate 0xfexxxxxx, enable,
516 * supervisor only, non-cacheable/
517 * serialized, writable */
522 /* Fetch tos version at Physical 2 */
523 /* We my not be able to access this address if the kernel is
524 loaded to st ram, since the first page is unmapped. On the
525 Medusa this is always the case and there is nothing we can do
526 about this, so we just assume the smaller offset. For the TT
527 we use the fact that in head.S we have set up a mapping
528 0xFFxxxxxx -> 0x00xxxxxx, so that the first 16MB is accessible
529 in the last 16MB of the address space. */
530 tos_version = (MACH_IS_MEDUSA || MACH_IS_HADES) ?
531 0xfff : *(unsigned short *)0xff000002;
532 atari_rtc_year_offset = (tos_version < 0x306) ? 70 : 68;
535 #ifdef CONFIG_HEARTBEAT
536 static void atari_heartbeat( int on )
541 if (atari_dont_touch_floppy_select)
546 sound_ym.rd_data_reg_sel = 14; /* Select PSG Port A */
547 tmp = sound_ym.rd_data_reg_sel;
548 sound_ym.wd_data = on ? (tmp & ~0x02) : (tmp | 0x02);
549 restore_flags(flags);
555 * This function does a reset on machines that lack the ability to
556 * assert the processor's _RESET signal somehow via hardware. It is
557 * based on the fact that you can find the initial SP and PC values
558 * after a reset at physical addresses 0 and 4. This works pretty well
559 * for Atari machines, since the lowest 8 bytes of physical memory are
560 * really ROM (mapped by hardware). For other 680x0 machines: don't
561 * know if it works...
563 * To get the values at addresses 0 and 4, the MMU better is turned
564 * off first. After that, we have to jump into physical address space
565 * (the PC before the pmove statement points to the virtual address of
566 * the code). Getting that physical address is not hard, but the code
567 * becomes a bit complex since I've tried to ensure that the jump
568 * statement after the pmove is in the cache already (otherwise the
569 * processor can't fetch it!). For that, the code first jumps to the
570 * jump statement with the (virtual) address of the pmove section in
571 * an address register . The jump statement is surely in the cache
572 * now. After that, that physical address of the reset code is loaded
573 * into the same address register, pmove is done and the same jump
574 * statements goes to the reset code. Since there are not many
575 * statements between the two jumps, I hope it stays in the cache.
577 * The C code makes heavy use of the GCC features that you can get the
578 * address of a C label. No hope to compile this with another compiler
582 /* ++andreas: no need for complicated code, just depend on prefetch */
584 static void atari_reset (void)
589 /* On the Medusa, phys. 0x4 may contain garbage because it's no
590 ROM. See above for explanation why we cannot use PTOV(4). */
591 reset_addr = MACH_IS_HADES ? 0x7fe00030 :
592 MACH_IS_MEDUSA || MACH_IS_AB40 ? 0xe00030 :
593 *(unsigned long *) 0xff000004;
595 /* reset ACIA for switch off OverScan, if it's active */
596 if (atari_switches & ATARI_SWITCH_OVSC_IKBD)
597 acia.key_ctrl = ACIA_RESET;
598 if (atari_switches & ATARI_SWITCH_OVSC_MIDI)
599 acia.mid_ctrl = ACIA_RESET;
601 /* processor independent: turn off interrupts and reset the VBR;
602 * the caches must be left enabled, else prefetching the final jump
603 * instruction doesn't work. */
610 if (CPU_IS_040_OR_060) {
611 unsigned long jmp_addr040 = virt_to_phys(&&jmp_addr_label040);
613 /* 68060: clear PCR to turn off superscalar operation */
617 "movec %%d0,%%pcr\n\t"
624 "andl #0xff000000,%/d0\n\t"
625 "orw #0xe020,%/d0\n\t" /* map 16 MB, enable, cacheable */
627 "movec %%d0,%%itt0\n\t"
628 "movec %%d0,%%dtt0\n\t"
643 "movec %%d0,%%tc\n\t"
645 /* the following setup of transparent translations is needed on the
646 * Afterburner040 to successfully reboot. Other machines shouldn't
647 * care about a different tt regs setup, they also didn't care in
648 * the past that the regs weren't turned off. */
649 "movel #0xffc000,%%d0\n\t" /* whole insn space cacheable */
650 "movec %%d0,%%itt0\n\t"
651 "movec %%d0,%%itt1\n\t"
652 "orw #0x40,%/d0\n\t" /* whole data space non-cacheable/ser. */
653 "movec %%d0,%%dtt0\n\t"
654 "movec %%d0,%%dtt1\n\t"
663 ("pmove %0@,%/tc\n\t"
666 : "a" (&tc_val), "a" (reset_addr));
670 static void atari_get_model(char *model)
672 strcpy(model, "Atari ");
673 switch (atari_mch_cookie >> 16) {
675 if (ATARIHW_PRESENT(MSTE_CLK))
676 strcat (model, "Mega ST");
678 strcat (model, "ST");
682 strcat (model, "Mega STE");
684 strcat (model, "STE");
688 /* Medusa has TT _MCH cookie */
689 strcat (model, "Medusa");
690 else if (MACH_IS_HADES)
691 strcat(model, "Hades");
693 strcat (model, "TT");
695 case ATARI_MCH_FALCON:
696 strcat (model, "Falcon");
698 strcat (model, " (with Afterburner040)");
701 sprintf (model + strlen (model), "(unknown mach cookie 0x%lx)",
708 static int atari_get_hardware_list(char *buffer)
712 for (i = 0; i < m68k_num_memory; i++)
713 len += sprintf (buffer+len, "\t%3ld MB at 0x%08lx (%s)\n",
714 m68k_memory[i].size >> 20, m68k_memory[i].addr,
715 (m68k_memory[i].addr & 0xff000000 ?
716 "alternate RAM" : "ST-RAM"));
718 #define ATARIHW_ANNOUNCE(name,str) \
719 if (ATARIHW_PRESENT(name)) \
720 len += sprintf (buffer + len, "\t%s\n", str)
722 len += sprintf (buffer + len, "Detected hardware:\n");
723 ATARIHW_ANNOUNCE(STND_SHIFTER, "ST Shifter");
724 ATARIHW_ANNOUNCE(EXTD_SHIFTER, "STe Shifter");
725 ATARIHW_ANNOUNCE(TT_SHIFTER, "TT Shifter");
726 ATARIHW_ANNOUNCE(VIDEL_SHIFTER, "Falcon Shifter");
727 ATARIHW_ANNOUNCE(YM_2149, "Programmable Sound Generator");
728 ATARIHW_ANNOUNCE(PCM_8BIT, "PCM 8 Bit Sound");
729 ATARIHW_ANNOUNCE(CODEC, "CODEC Sound");
730 ATARIHW_ANNOUNCE(TT_SCSI, "SCSI Controller NCR5380 (TT style)");
731 ATARIHW_ANNOUNCE(ST_SCSI, "SCSI Controller NCR5380 (Falcon style)");
732 ATARIHW_ANNOUNCE(ACSI, "ACSI Interface");
733 ATARIHW_ANNOUNCE(IDE, "IDE Interface");
734 ATARIHW_ANNOUNCE(FDCSPEED, "8/16 Mhz Switch for FDC");
735 ATARIHW_ANNOUNCE(ST_MFP, "Multi Function Peripheral MFP 68901");
736 ATARIHW_ANNOUNCE(TT_MFP, "Second Multi Function Peripheral MFP 68901");
737 ATARIHW_ANNOUNCE(SCC, "Serial Communications Controller SCC 8530");
738 ATARIHW_ANNOUNCE(ST_ESCC, "Extended Serial Communications Controller SCC 85230");
739 ATARIHW_ANNOUNCE(ANALOG_JOY, "Paddle Interface");
740 ATARIHW_ANNOUNCE(MICROWIRE, "MICROWIRE(tm) Interface");
741 ATARIHW_ANNOUNCE(STND_DMA, "DMA Controller (24 bit)");
742 ATARIHW_ANNOUNCE(EXTD_DMA, "DMA Controller (32 bit)");
743 ATARIHW_ANNOUNCE(SCSI_DMA, "DMA Controller for NCR5380");
744 ATARIHW_ANNOUNCE(SCC_DMA, "DMA Controller for SCC");
745 ATARIHW_ANNOUNCE(TT_CLK, "Clock Chip MC146818A");
746 ATARIHW_ANNOUNCE(MSTE_CLK, "Clock Chip RP5C15");
747 ATARIHW_ANNOUNCE(SCU, "System Control Unit");
748 ATARIHW_ANNOUNCE(BLITTER, "Blitter");
749 ATARIHW_ANNOUNCE(VME, "VME Bus");
750 ATARIHW_ANNOUNCE(DSP56K, "DSP56001 processor");