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