root/arch/m68k/atari/config.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hwreg_present
  2. hwreg_present_bywrite
  3. hwreg_write
  4. scc_test
  5. config_atari
  6. atari_sched_init
  7. atari_gettimeoffset
  8. mste_read
  9. mste_write
  10. atari_mste_gettod
  11. atari_gettod
  12. atari_mste_hwclk
  13. atari_hwclk
  14. atari_mste_set_clock_mmss
  15. atari_set_clock_mmss
  16. atari_waitbut
  17. ata_mfp_out
  18. ata_mfp_print
  19. ata_scc_out
  20. ata_scc_print
  21. ata_par_out
  22. ata_par_print
  23. atari_debug_init
  24. ata_serial_print
  25. atari_reset
  26. atari_get_model
  27. atari_get_hardware_list

   1 /*
   2  *  linux/atari/config.c
   3  *
   4  *  Copyright (C) 1994 Bj”rn 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 README.legal 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 <asm/bootinfo.h>
  31 #include <linux/mc146818rtc.h>
  32 #include <linux/kd.h>
  33 #include <linux/tty.h>
  34 #include <linux/console.h>
  35 
  36 #include <asm/atarihw.h>
  37 #include <asm/atarihdreg.h>
  38 #include <asm/atariints.h>
  39 
  40 #include <asm/system.h>
  41 #include <asm/io.h>
  42 #include <asm/irq.h>
  43 #include <asm/pgtable.h>
  44 #include <asm/machdep.h>
  45 
  46 extern void atari_sched_init(isrfunc);
  47 extern int atari_keyb_init(void);
  48 extern int atari_kbdrate (struct kbd_repeat *);
  49 extern void atari_kbd_leds (unsigned int);
  50 extern void atari_init_INTS (void);
  51 extern int atari_add_isr (unsigned long, isrfunc, int, void *, char *);
  52 extern int atari_remove_isr (unsigned long, isrfunc);
  53 extern void atari_enable_irq (unsigned);
  54 extern void atari_disable_irq (unsigned);
  55 extern int atari_get_irq_list (char *buf, int len);
  56 extern unsigned long atari_gettimeoffset (void);
  57 extern void atari_mste_gettod (int *, int *, int *, int *, int *, int *);
  58 extern void atari_gettod (int *, int *, int *, int *, int *, int *);
  59 extern int atari_mste_hwclk (int, struct hwclk_time *);
  60 extern int atari_hwclk (int, struct hwclk_time *);
  61 extern int atari_mste_set_clock_mmss (unsigned long);
  62 extern int atari_set_clock_mmss (unsigned long);
  63 extern void atari_check_partition (struct gendisk *hd, unsigned int dev);
  64 extern void atari_mksound( unsigned int count, unsigned int ticks );
  65 extern void atari_reset( void );
  66 #ifdef CONFIG_BLK_DEV_FD
  67 extern int atari_floppy_init (void);
  68 extern void atari_floppy_setup(char *, int *);
  69 #endif
  70 extern void atari_waitbut (void);
  71 extern struct consw fb_con;
  72 extern struct fb_info *atari_fb_init(long *);
  73 extern void atari_debug_init (void);
  74 extern void atari_video_setup(char *, int *);
  75 
  76 extern void (*kd_mksound)(unsigned int, unsigned int);
  77 
  78 /* This function tests for the presence of an address, specially a
  79  * hardware register address. It is called very early in the kernel
  80  * initialization process, when the VBR register isn't set up yet. On
  81  * an Atari, it still points to address 0, which is unmapped. So a bus
  82  * error would cause another bus error while fetching the exception
  83  * vector, and the CPU would do nothing at all. So we needed to set up
  84  * a temporary VBR and a vector table for the duration of the test.
  85  */
  86 
  87 static int hwreg_present( volatile void *regp )
     /* [previous][next][first][last][top][bottom][index][help] */
  88 {
  89     int ret = 0;
  90     long        save_sp, save_vbr;
  91     long        tmp_vectors[3];
  92 
  93     __asm__ __volatile__
  94         (       "movec  %/vbr,%2\n\t"
  95                 "movel  #Lberr1,%4@(8)\n\t"
  96                 "movec  %4,%/vbr\n\t"
  97                 "movel  %/sp,%1\n\t"
  98                 "moveq  #0,%0\n\t"
  99                 "tstb   %3@\n\t"  
 100                 "nop\n\t"
 101                 "moveq  #1,%0\n"
 102                 "Lberr1:\n\t"
 103                 "movel  %1,%/sp\n\t"
 104                 "movec  %2,%/vbr"
 105                 : "=&d" (ret), "=&r" (save_sp), "=&r" (save_vbr)
 106                 : "a" (regp), "a" (tmp_vectors)
 107                 );
 108 
 109     return( ret );
 110 }
 111   
 112 #if 0
 113 static int hwreg_present_bywrite( volatile void *regp,
     /* [previous][next][first][last][top][bottom][index][help] */
 114                                  unsigned char val )
 115 
 116 {
 117     int         ret;
 118     long        save_sp, save_vbr;
 119     static long tmp_vectors[3] = { 0, 0, (long)&&after_test };
 120         
 121     __asm__ __volatile__
 122         (       "movec  %/vbr,%2\n\t"   /* save vbr value            */
 123                 "movec  %4,%/vbr\n\t"   /* set up temporary vectors  */
 124                 "movel  %/sp,%1\n\t"    /* save sp                   */
 125                 "moveq  #0,%0\n\t"      /* assume not present        */
 126                 "moveb  %5,%3@\n\t"     /* write the hardware reg    */
 127                 "cmpb   %3@,%5\n\t"     /* compare it                */
 128                 "seq    %0"             /* comes here only if reg    */
 129                                         /* is present                */
 130                 : "=d&" (ret), "=r&" (save_sp), "=r&" (save_vbr)
 131                 : "a" (regp), "r" (tmp_vectors), "d" (val)
 132                 );
 133   after_test:
 134     __asm__ __volatile__
 135       ( "movel  %0,%/sp\n\t"            /* restore sp                */
 136         "movec  %1,%/vbr"                       /* restore vbr               */
 137         : : "r" (save_sp), "r" (save_vbr) : "sp"
 138         );
 139 
 140     return( ret );
 141 }
 142 #endif
 143 
 144 /* Basically the same, but writes a value into a word register, protected
 145  * by a bus error handler */
 146 
 147 static int hwreg_write( volatile void *regp, unsigned short val )
     /* [previous][next][first][last][top][bottom][index][help] */
 148 {
 149         int             ret;
 150         long    save_sp, save_vbr;
 151         long    tmp_vectors[3];
 152 
 153         __asm__ __volatile__
 154         (       "movec  %/vbr,%2\n\t"
 155                 "movel  #Lberr2,%4@(8)\n\t"
 156                 "movec  %4,%/vbr\n\t"
 157                 "movel  %/sp,%1\n\t"
 158                 "moveq  #0,%0\n\t"
 159                 "movew  %5,%3@\n\t"  
 160                 "nop    \n\t"   /* If this nop isn't present, 'ret' may already be
 161                                  * loaded with 1 at the time the bus error
 162                                  * happens! */
 163                 "moveq  #1,%0\n"
 164         "Lberr2:\n\t"
 165                 "movel  %1,%/sp\n\t"
 166                 "movec  %2,%/vbr"
 167                 : "=&d" (ret), "=&r" (save_sp), "=&r" (save_vbr)
 168                 : "a" (regp), "a" (tmp_vectors), "g" (val)
 169         );
 170 
 171         return( ret );
 172 }
 173 
 174 /* ++roman: This is a more elaborate test for an SCC chip, since the plain
 175  * Medusa board generates DTACK at the SCC's standard addresses, but a SCC
 176  * board in the Medusa is possible. Also, the addresses where the ST_ESCC
 177  * resides generate DTACK without the chip, too.
 178  * The method is to write values into the interrupt vector register, that
 179  * should be readable without trouble (from channel A!).
 180  */
 181 
 182 static int scc_test( volatile char *ctla )
     /* [previous][next][first][last][top][bottom][index][help] */
 183 {
 184         if (!hwreg_present( ctla ))
 185                 return( 0 );
 186         MFPDELAY();
 187 
 188         *ctla = 2; MFPDELAY();
 189         *ctla = 0x40; MFPDELAY();
 190         
 191         *ctla = 2; MFPDELAY();
 192         if (*ctla != 0x40) return( 0 );
 193         MFPDELAY();
 194 
 195         *ctla = 2; MFPDELAY();
 196         *ctla = 0x60; MFPDELAY();
 197         
 198         *ctla = 2; MFPDELAY();
 199         if (*ctla != 0x60) return( 0 );
 200 
 201         return( 1 );
 202 }
 203 
 204 void config_atari(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 205 {
 206     mach_sched_init      = atari_sched_init;
 207     mach_keyb_init       = atari_keyb_init;
 208     mach_kbdrate         = atari_kbdrate;
 209     mach_kbd_leds        = atari_kbd_leds;
 210     mach_init_INTS       = atari_init_INTS;
 211     mach_add_isr         = atari_add_isr;
 212     mach_remove_isr      = atari_remove_isr;
 213     mach_enable_irq      = atari_enable_irq;
 214     mach_disable_irq     = atari_disable_irq;
 215     mach_get_irq_list    = atari_get_irq_list;
 216     mach_gettimeoffset   = atari_gettimeoffset;
 217     mach_check_partition = atari_check_partition;
 218     mach_mksound         = atari_mksound;
 219     mach_reset           = atari_reset;
 220 #ifdef CONFIG_BLK_DEV_FD
 221     mach_floppy_init     = atari_floppy_init;
 222     mach_floppy_setup    = atari_floppy_setup;
 223 #endif
 224     conswitchp           = &fb_con;
 225     waitbut              = atari_waitbut;
 226     mach_fb_init         = atari_fb_init;
 227     mach_max_dma_address = 0xffffff;
 228     mach_debug_init      = atari_debug_init;
 229     mach_video_setup     = atari_video_setup;
 230     kd_mksound           = atari_mksound;
 231 
 232     /* ++bjoern: 
 233      * Determine hardware present
 234      */
 235 
 236     printk( "Atari hardware found: " );
 237     if (is_medusa) {
 238         /* There's no Atari video hardware on the Medusa, but all the
 239          * addresses below generate a DTACK so no bus error occurs! */
 240     }
 241     else if (hwreg_present( f030_xreg )) {
 242         ATARIHW_SET(VIDEL_SHIFTER);
 243         printk( "VIDEL " );
 244         /* This is a temporary hack: If there is Falcon video
 245          * hardware, we assume that the ST-DMA serves SCSI instead of
 246          * ACSI. In the future, there should be a better method for
 247          * this...
 248          */
 249         ATARIHW_SET(ST_SCSI);
 250         printk( "STDMA-SCSI " );
 251     }
 252     else if (hwreg_present( tt_palette )) {
 253         ATARIHW_SET(TT_SHIFTER);
 254         printk( "TT_SHIFTER " );
 255     }
 256     else if (hwreg_present( &shifter.bas_hi )) {
 257         if (hwreg_present( &shifter.bas_lo ) &&
 258             (shifter.bas_lo = 0x0aau, shifter.bas_lo == 0x0aau)) {
 259             ATARIHW_SET(EXTD_SHIFTER);
 260             printk( "EXTD_SHIFTER " );
 261         }
 262         else {
 263             ATARIHW_SET(STND_SHIFTER);
 264             printk( "STND_SHIFTER " );
 265         }
 266     }
 267     if (hwreg_present( &mfp.par_dt_reg )) {
 268         ATARIHW_SET(ST_MFP);
 269         printk( "ST_MFP " );
 270     }
 271     if (hwreg_present( &tt_mfp.par_dt_reg )) {
 272         ATARIHW_SET(TT_MFP);
 273         printk( "TT_MFP " );
 274     }
 275     if (hwreg_present( &tt_scsi_dma.dma_addr_hi )) {
 276         ATARIHW_SET(SCSI_DMA);
 277         printk( "TT_SCSI_DMA " );
 278     }
 279     if (hwreg_present( &st_dma.dma_hi )) {
 280         ATARIHW_SET(STND_DMA);
 281         printk( "STND_DMA " );
 282     }
 283     if (is_medusa || /* The ST-DMA address registers aren't readable
 284                       * on all Medusas, so the test below may fail */
 285         (hwreg_present( &st_dma.dma_vhi ) &&
 286          (st_dma.dma_vhi = 0x55) && (st_dma.dma_hi = 0xaa) &&
 287          st_dma.dma_vhi == 0x55 && st_dma.dma_hi == 0xaa &&
 288          (st_dma.dma_vhi = 0xaa) && (st_dma.dma_hi = 0x55) &&
 289          st_dma.dma_vhi == 0xaa && st_dma.dma_hi == 0x55)) {
 290         ATARIHW_SET(EXTD_DMA);
 291         printk( "EXTD_DMA " );
 292     }
 293     if (hwreg_present( &tt_scsi.scsi_data )) {
 294         ATARIHW_SET(TT_SCSI);
 295         printk( "TT_SCSI " );
 296     }
 297     if (hwreg_present( &sound_ym.rd_data_reg_sel )) {
 298         ATARIHW_SET(YM_2149);
 299         printk( "YM2149 " );
 300     }
 301     if (!is_medusa && hwreg_present( &tt_dmasnd.ctrl )) {
 302         ATARIHW_SET(PCM_8BIT);
 303         printk( "PCM " );
 304     }
 305     if (hwreg_present( (void *)(0xffff8940) )) {
 306         ATARIHW_SET(CODEC);
 307         printk( "CODEC " );
 308     }
 309     if (hwreg_present( &tt_scc_dma.dma_ctrl ) &&
 310 #if 0
 311         /* This test sucks! Who knows some better? */
 312         (tt_scc_dma.dma_ctrl = 0x01, (tt_scc_dma.dma_ctrl & 1) == 1) &&
 313         (tt_scc_dma.dma_ctrl = 0x00, (tt_scc_dma.dma_ctrl & 1) == 0)
 314 #else
 315         !is_medusa
 316 #endif
 317         ) {
 318         ATARIHW_SET(SCC_DMA);
 319         printk( "SCC_DMA " );
 320     }
 321     if (scc_test( &scc.cha_a_ctrl )) {
 322         ATARIHW_SET(SCC);
 323         printk( "SCC " );
 324     }
 325     if (scc_test( &st_escc.cha_b_ctrl )) {
 326         ATARIHW_SET( ST_ESCC );
 327         printk( "ST_ESCC " );
 328     }
 329     if (hwreg_present( &tt_scu.sys_mask )) {
 330         ATARIHW_SET(SCU);
 331         /* Assume a VME bus if there's a SCU */
 332         ATARIHW_SET( VME );
 333         printk( "VME SCU " );
 334     }
 335     if (hwreg_present( (void *)(0xffff9210) )) {
 336         ATARIHW_SET(ANALOG_JOY);
 337         printk( "ANALOG_JOY " );
 338     }
 339     if (hwreg_present( blitter.halftone )) {
 340         ATARIHW_SET(BLITTER);
 341         printk( "BLITTER " );
 342     }
 343     if (hwreg_present( (void *)(ATA_HD_BASE+ATA_HD_CMD) )) {
 344         ATARIHW_SET(IDE);
 345         printk( "IDE " );
 346     }
 347 #if 1 /* This maybe wrong */
 348     if (!is_medusa &&
 349         hwreg_present( &tt_microwire.data ) &&
 350         hwreg_present( &tt_microwire.mask ) &&
 351         (tt_microwire.mask = 0x7ff,
 352          tt_microwire.data = MW_LM1992_PSG_HIGH | MW_LM1992_ADDR,
 353          tt_microwire.data != 0)) {
 354         ATARIHW_SET(MICROWIRE);
 355         while (tt_microwire.mask != 0x7ff) ;
 356         printk( "MICROWIRE " );
 357     }
 358 #endif
 359     if (hwreg_present( &tt_rtc.regsel )) {
 360         ATARIHW_SET(TT_CLK);
 361         printk( "TT_CLK " );
 362         mach_gettod = atari_gettod;
 363         mach_hwclk = atari_hwclk;
 364         mach_set_clock_mmss = atari_set_clock_mmss;
 365     }
 366     if (hwreg_present( &mste_rtc.sec_ones)) {
 367         ATARIHW_SET(MSTE_CLK);
 368         printk( "MSTE_CLK ");
 369         mach_gettod = atari_mste_gettod;
 370         mach_hwclk = atari_mste_hwclk;
 371         mach_set_clock_mmss = atari_mste_set_clock_mmss;
 372     }
 373     if (!is_medusa &&
 374         hwreg_present( &dma_wd.fdc_speed ) &&
 375         hwreg_write( &dma_wd.fdc_speed, 0 )) {
 376             ATARIHW_SET(FDCSPEED);
 377             printk( "FDC_SPEED ");
 378     }
 379     if (!ATARIHW_PRESENT(ST_SCSI)) {
 380         ATARIHW_SET(ACSI);
 381         printk( "ACSI " );
 382     }
 383     printk("\n");
 384 
 385     if (m68k_is040or060)
 386         /* Now it seems to be safe to turn of the tt0 transparent
 387          * translation (the one that must not be turned off in
 388          * head.S...)
 389          */
 390         __asm__ volatile ("moveq #0,%/d0;"
 391                           ".long 0x4e7b0004;"   /* movec d0,itt0 */
 392                           ".long 0x4e7b0006;"   /* movec d0,dtt0 */
 393                                                   : /* no outputs */
 394                                                   : /* no inputs */
 395                                                   : "d0");
 396         
 397     /* allocator for memory that must reside in st-ram */
 398     atari_stram_init ();
 399 
 400     /* Set up a mapping for the VMEbus address region:
 401      *
 402      * VME is either at phys. 0xfexxxxxx (TT) or 0xa00000..0xdfffff
 403      * (MegaSTE) In both cases, the whole 16 MB chunk is mapped at
 404      * 0xfe000000 virt., because this can be done with a single
 405      * transparent translation. On the 68040, lots of often unused
 406      * page tables would be needed otherwise. On a MegaSTE or similar,
 407      * the highest byte is stripped off by hardware due to the 24 bit
 408      * design of the bus.
 409      */
 410 
 411     if (!m68k_is040or060) {
 412         unsigned long   tt1_val;
 413         tt1_val = 0xfe008543;   /* Translate 0xfexxxxxx, enable, cache
 414                                  * inhibit, read and write, FDC mask = 3,
 415                                  * FDC val = 4 -> Supervisor only */
 416         __asm__ __volatile__ ( "pmove   %0@,%/tt1" : : "a" (&tt1_val) );
 417     }
 418     else {
 419         __asm__ __volatile__
 420             ( "movel %0,%/d0\n\t"
 421               ".long 0x4e7b0005\n\t"    /* movec d0,itt1 */
 422               ".long 0x4e7b0007"        /* movec d0,dtt1 */
 423               :
 424               : "g" (0xfe00a040)        /* Translate 0xfexxxxxx, enable,
 425                                          * supervisor only, non-cacheable/
 426                                          * serialized, writable */
 427               : "d0" );
 428 
 429     }
 430 }
 431 
 432 void atari_sched_init (isrfunc timer_routine)
     /* [previous][next][first][last][top][bottom][index][help] */
 433 {
 434     /* set Timer C data Register */
 435     mfp.tim_dt_c = INT_TICKS;
 436     /* start timer C, div = 1:100 */
 437     mfp.tim_ct_cd = (mfp.tim_ct_cd & 15) | 0x60; 
 438     /* install interrupt service routine for MFP Timer C */
 439     add_isr (IRQ_MFP_TIMC, timer_routine, IRQ_TYPE_SLOW, NULL, "timer");
 440 }
 441 
 442 /* ++andreas: gettimeoffset fixed to check for pending interrupt */
 443 
 444 #define TICK_SIZE 10000
 445   
 446 /* This is always executed with interrupts disabled.  */
 447 unsigned long atari_gettimeoffset (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 448 {
 449   unsigned long ticks, offset = 0;
 450 
 451   /* read MFP timer C current value */
 452   ticks = mfp.tim_dt_c;
 453   /* The probability of underflow is less than 2% */
 454   if (ticks > INT_TICKS - INT_TICKS / 50)
 455     /* Check for pending timer interrupt */
 456     if (mfp.int_pn_b & (1 << 5))
 457       offset = TICK_SIZE;
 458 
 459   ticks = INT_TICKS - ticks;
 460   ticks = ticks * 10000L / INT_TICKS;
 461 
 462   return ticks + offset;
 463 }
 464 
 465 
 466 static void
 467 mste_read(struct MSTE_RTC *val)
     /* [previous][next][first][last][top][bottom][index][help] */
 468 {
 469 #define COPY(v) val->v=(mste_rtc.v & 0xf)
 470         do {
 471                 COPY(sec_ones) ; COPY(sec_tens) ; COPY(min_ones) ; 
 472                 COPY(min_tens) ; COPY(hr_ones) ; COPY(hr_tens) ; 
 473                 COPY(weekday) ; COPY(day_ones) ; COPY(day_tens) ; 
 474                 COPY(mon_ones) ; COPY(mon_tens) ; COPY(year_ones) ;
 475                 COPY(year_tens) ;
 476         /* prevent from reading the clock while it changed */
 477         } while (val->sec_ones != (mste_rtc.sec_ones & 0xf));
 478 #undef COPY
 479 }
 480 
 481 static void
 482 mste_write(struct MSTE_RTC *val)
     /* [previous][next][first][last][top][bottom][index][help] */
 483 {
 484 #define COPY(v) mste_rtc.v=val->v
 485         do {
 486                 COPY(sec_ones) ; COPY(sec_tens) ; COPY(min_ones) ; 
 487                 COPY(min_tens) ; COPY(hr_ones) ; COPY(hr_tens) ; 
 488                 COPY(weekday) ; COPY(day_ones) ; COPY(day_tens) ; 
 489                 COPY(mon_ones) ; COPY(mon_tens) ; COPY(year_ones) ;
 490                 COPY(year_tens) ;
 491         /* prevent from writing the clock while it changed */
 492         } while (val->sec_ones != (mste_rtc.sec_ones & 0xf));
 493 #undef COPY
 494 }
 495 
 496 #define RTC_READ(reg)                           \
 497     ({  unsigned char   __val;                  \
 498                 outb(reg,&tt_rtc.regsel);       \
 499                 __val = tt_rtc.data;            \
 500                 __val;                          \
 501         })
 502 
 503 #define RTC_WRITE(reg,val)                      \
 504     do {                                        \
 505                 outb(reg,&tt_rtc.regsel);       \
 506                 tt_rtc.data = (val);            \
 507         } while(0)
 508 
 509 
 510 void atari_mste_gettod (int *yearp, int *monp, int *dayp,
     /* [previous][next][first][last][top][bottom][index][help] */
 511                         int *hourp, int *minp, int *secp)
 512 {
 513     int hr24=0;
 514     struct MSTE_RTC val;
 515 
 516     mste_rtc.mode=(mste_rtc.mode | 1);
 517     hr24=mste_rtc.mon_tens & 1;
 518     mste_rtc.mode=(mste_rtc.mode & ~1);
 519 
 520     mste_read(&val);
 521     *secp = val.sec_ones + val.sec_tens * 10;
 522     *minp = val.min_ones + val.min_tens * 10;
 523     if (hr24)
 524         *hourp = val.hr_ones + val.hr_tens * 10;
 525     else {
 526         *hourp = val.hr_ones + (val.hr_tens & 1) * 10;
 527         if (val.hr_tens & 2)
 528             *hourp += 12;
 529     }
 530     *dayp = val.day_ones + val.day_tens * 10;
 531     *monp = val.mon_ones + val.mon_tens * 10;
 532     *yearp = val.year_ones + val.year_tens * 10 + 80;   
 533 }
 534 
 535   
 536 void atari_gettod (int *yearp, int *monp, int *dayp,
     /* [previous][next][first][last][top][bottom][index][help] */
 537                    int *hourp, int *minp, int *secp)
 538 {
 539     unsigned char       ctrl;
 540     unsigned short tos_version;
 541                 
 542     while (!(RTC_READ(RTC_FREQ_SELECT) & RTC_UIP)) ;
 543     while (RTC_READ(RTC_FREQ_SELECT) & RTC_UIP) ;
 544 
 545     *secp  = RTC_READ(RTC_SECONDS);
 546     *minp  = RTC_READ(RTC_MINUTES);
 547     *hourp = RTC_READ(RTC_HOURS);
 548     *dayp  = RTC_READ(RTC_DAY_OF_MONTH);
 549     *monp  = RTC_READ(RTC_MONTH);
 550     *yearp = RTC_READ(RTC_YEAR);
 551 
 552     ctrl = RTC_READ(RTC_CONTROL); 
 553 
 554     if (!(ctrl & RTC_DM_BINARY)) {
 555         BCD_TO_BIN(*secp);
 556         BCD_TO_BIN(*minp);
 557         BCD_TO_BIN(*hourp);
 558         BCD_TO_BIN(*dayp);
 559         BCD_TO_BIN(*monp);
 560         BCD_TO_BIN(*yearp);
 561     }
 562     if (!(ctrl & RTC_24H)) {
 563         if (*hourp & 0x80) {
 564             *hourp &= ~0x80;
 565             *hourp += 12;
 566         }
 567     }
 568     /* Adjust values (let the setup valid) */
 569 
 570     /* Fetch tos version at Physical 2 */
 571     /* We my not be able to access this address if the kernel is
 572        loaded to st ram, since the first page is unmapped.  On the
 573        Medusa this is always the case and there is nothing we can do
 574        about this, so we just assume the smaller offset.  For the TT
 575        we use the fact that in head.S we have set up a mapping
 576        0xFFxxxxxx -> 0x00xxxxxx, so that the first 16MB is accessible
 577        in the last 16MB of the address space. */
 578     tos_version = is_medusa ? 0xfff : *(unsigned short *)0xFF000002;
 579     *yearp += (tos_version < 0x306) ? 70 : 68;
 580 }
 581 
 582 #define HWCLK_POLL_INTERVAL     5
 583 
 584 int atari_mste_hwclk( int op, struct hwclk_time *t )
     /* [previous][next][first][last][top][bottom][index][help] */
 585 {
 586     int hour, year;
 587     int hr24=0;
 588     struct MSTE_RTC val;
 589     
 590     mste_rtc.mode=(mste_rtc.mode | 1);
 591     hr24=mste_rtc.mon_tens & 1;
 592     mste_rtc.mode=(mste_rtc.mode & ~1);
 593 
 594     if (op) {
 595         /* write: prepare values */
 596         
 597         val.sec_ones = t->sec % 10;
 598         val.sec_tens = t->sec / 10;
 599         val.min_ones = t->min % 10;
 600         val.min_tens = t->min / 10;
 601         hour = t->hour;
 602         val.hr_ones = hour % 10;
 603         val.hr_tens = hour / 10;
 604         if (!hr24  && hour > 11) {
 605             hour -= 12;
 606             val.hr_ones = hour % 10;
 607             val.hr_tens = (hour / 10) | 2;
 608         }
 609         val.day_ones = t->day % 10;
 610         val.day_tens = t->day / 10;
 611         val.mon_ones = (t->mon+1) % 10;
 612         val.mon_tens = (t->mon+1) / 10;
 613         year = t->year - 80;
 614         val.year_ones = year % 10;
 615         val.year_tens = year / 10;
 616         val.weekday = t->wday;
 617         mste_write(&val);
 618         mste_rtc.mode=(mste_rtc.mode | 1);
 619         val.year_ones = (year % 4);     /* leap year register */
 620         mste_rtc.mode=(mste_rtc.mode & ~1);
 621     }
 622     else {
 623         mste_read(&val);
 624         t->sec = val.sec_ones + val.sec_tens * 10;
 625         t->min = val.min_ones + val.min_tens * 10;
 626         if (hr24)
 627             t->hour = val.hr_ones + val.hr_tens * 10;
 628         else {
 629             t->hour = val.hr_ones + (val.hr_tens & 1) * 10;
 630             if (val.hr_tens & 2)
 631                 t->hour += 12;
 632         }
 633         t->day = val.day_ones + val.day_tens * 10;
 634         t->mon = val.mon_ones + val.mon_tens * 10 - 1;
 635         t->year = val.year_ones + val.year_tens * 10 + 80;
 636         t->wday = val.weekday;
 637     }
 638     return 0;
 639 }
 640 
 641 int atari_hwclk( int op, struct hwclk_time *t )
     /* [previous][next][first][last][top][bottom][index][help] */
 642 {
 643     int sec=0, min=0, hour=0, day=0, mon=0, year=0, wday=0; 
 644     unsigned long       flags;
 645     unsigned short      tos_version;
 646     unsigned char       ctrl;
 647 
 648     /* Tos version at Physical 2.  See above for explanation why we
 649        cannot use PTOV(2).  */
 650     tos_version = is_medusa ? 0xfff : *(unsigned short *)0xff000002;
 651 
 652     ctrl = RTC_READ(RTC_CONTROL); /* control registers are
 653                                    * independant from the UIP */
 654 
 655     if (op) {
 656         /* write: prepare values */
 657         
 658         sec  = t->sec;
 659         min  = t->min;
 660         hour = t->hour;
 661         day  = t->day;
 662         mon  = t->mon + 1;
 663         year = t->year - ((tos_version < 0x306) ? 70 : 68);
 664         wday = t->wday + (t->wday >= 0);
 665         
 666         if (!(ctrl & RTC_24H) && hour > 11) {
 667             hour -= 12;
 668             hour |= 0x80;
 669         }
 670         
 671         if (!(ctrl & RTC_DM_BINARY)) {
 672             BIN_TO_BCD(sec);
 673             BIN_TO_BCD(min);
 674             BIN_TO_BCD(hour);
 675             BIN_TO_BCD(day);
 676             BIN_TO_BCD(mon);
 677             BIN_TO_BCD(year);
 678             if (wday >= 0) BIN_TO_BCD(wday);
 679         }
 680     }
 681     
 682     /* Reading/writing the clock registers is a bit critical due to
 683      * the regular update cycle of the RTC. While an update is in
 684      * progress, registers 0..9 shouldn't be touched.
 685      * The problem is solved like that: If an update is currently in
 686      * progress (the UIP bit is set), the process sleeps for a while
 687      * (50ms). This really should be enough, since the update cycle
 688      * normally needs 2 ms.
 689      * If the UIP bit reads as 0, we have at least 244 usecs until the
 690      * update starts. This should be enough... But to be sure,
 691      * additionally the RTC_SET bit is set to prevent an update cycle.
 692      */
 693 
 694     while( RTC_READ(RTC_FREQ_SELECT) & RTC_UIP ) {
 695         current->state = TASK_INTERRUPTIBLE;
 696         current->timeout = jiffies + HWCLK_POLL_INTERVAL;
 697         schedule();
 698     }
 699 
 700     save_flags(flags);
 701     cli();
 702     RTC_WRITE( RTC_CONTROL, ctrl | RTC_SET );
 703     if (!op) {
 704         sec  = RTC_READ( RTC_SECONDS );
 705         min  = RTC_READ( RTC_MINUTES );
 706         hour = RTC_READ( RTC_HOURS );
 707         day  = RTC_READ( RTC_DAY_OF_MONTH );
 708         mon  = RTC_READ( RTC_MONTH );
 709         year = RTC_READ( RTC_YEAR );
 710         wday = RTC_READ( RTC_DAY_OF_WEEK );
 711     }
 712     else {
 713         RTC_WRITE( RTC_SECONDS, sec );
 714         RTC_WRITE( RTC_MINUTES, min );
 715         RTC_WRITE( RTC_HOURS, hour );
 716         RTC_WRITE( RTC_DAY_OF_MONTH, day );
 717         RTC_WRITE( RTC_MONTH, mon );
 718         RTC_WRITE( RTC_YEAR, year );
 719         if (wday >= 0) RTC_WRITE( RTC_DAY_OF_WEEK, wday );
 720     }
 721     RTC_WRITE( RTC_CONTROL, ctrl & ~RTC_SET );
 722     restore_flags(flags);
 723 
 724     if (!op) {
 725         /* read: adjust values */
 726         
 727         if (!(ctrl & RTC_DM_BINARY)) {
 728             BCD_TO_BIN(sec);
 729             BCD_TO_BIN(min);
 730             BCD_TO_BIN(hour);
 731             BCD_TO_BIN(day);
 732             BCD_TO_BIN(mon);
 733             BCD_TO_BIN(year);
 734             BCD_TO_BIN(wday);
 735         }
 736 
 737         if (!(ctrl & RTC_24H)) {
 738             if (hour & 0x80) {
 739                 hour &= ~0x80;
 740                 hour += 12;
 741             }
 742         }
 743 
 744         t->sec  = sec;
 745         t->min  = min;
 746         t->hour = hour;
 747         t->day  = day;
 748         t->mon  = mon - 1;
 749         t->year = year + ((tos_version < 0x306) ? 70 : 68);
 750         t->wday = wday - 1;
 751     }
 752 
 753     return( 0 );
 754 }
 755 
 756 
 757 int atari_mste_set_clock_mmss (unsigned long nowtime)
     /* [previous][next][first][last][top][bottom][index][help] */
 758 {
 759     short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
 760     struct MSTE_RTC val;
 761     unsigned char rtc_minutes;
 762 
 763     mste_read(&val);  
 764     rtc_minutes= val.min_ones + val.min_tens * 10;
 765     if ((rtc_minutes < real_minutes
 766          ? real_minutes - rtc_minutes
 767          : rtc_minutes - real_minutes) < 30)
 768     {
 769         val.sec_ones = real_seconds % 10;
 770         val.sec_tens = real_seconds / 10;
 771         val.min_ones = real_minutes % 10;
 772         val.min_tens = real_minutes / 10;
 773         mste_write(&val);
 774     }
 775     else
 776         return -1;
 777     return 0;
 778 }
 779 
 780 int atari_set_clock_mmss (unsigned long nowtime)
     /* [previous][next][first][last][top][bottom][index][help] */
 781 {
 782     int retval = 0;
 783     short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
 784     unsigned char save_control, save_freq_select, rtc_minutes;
 785 
 786     save_control = RTC_READ (RTC_CONTROL); /* tell the clock it's being set */
 787     RTC_WRITE (RTC_CONTROL, save_control | RTC_SET);
 788 
 789     save_freq_select = RTC_READ (RTC_FREQ_SELECT); /* stop and reset prescaler */
 790     RTC_WRITE (RTC_FREQ_SELECT, save_freq_select | RTC_DIV_RESET2);
 791 
 792     rtc_minutes = RTC_READ (RTC_MINUTES);
 793     if (!(save_control & RTC_DM_BINARY))
 794         BCD_TO_BIN (rtc_minutes);
 795 
 796     /* Since we're only adjusting minutes and seconds, don't interfere
 797        with hour overflow.  This avoids messing with unknown time zones
 798        but requires your RTC not to be off by more than 30 minutes.  */
 799     if ((rtc_minutes < real_minutes
 800          ? real_minutes - rtc_minutes
 801          : rtc_minutes - real_minutes) < 30)
 802         {
 803             if (!(save_control & RTC_DM_BINARY))
 804                 {
 805                     BIN_TO_BCD (real_seconds);
 806                     BIN_TO_BCD (real_minutes);
 807                 }
 808             RTC_WRITE (RTC_SECONDS, real_seconds);
 809             RTC_WRITE (RTC_MINUTES, real_minutes);
 810         }
 811     else
 812         retval = -1;
 813 
 814     RTC_WRITE (RTC_FREQ_SELECT, save_freq_select);
 815     RTC_WRITE (RTC_CONTROL, save_control);
 816     return retval;
 817 }
 818 
 819 
 820 void atari_waitbut (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 821 {
 822     /* sorry, no-op */
 823 }
 824 
 825 
 826 static inline void ata_mfp_out (char c)
     /* [previous][next][first][last][top][bottom][index][help] */
 827 {
 828     while (!(mfp.trn_stat & 0x80)) /* wait for tx buf empty */
 829         barrier ();
 830     mfp.usart_dta = c;
 831 }
 832 
 833 void ata_mfp_print (const char *str)
     /* [previous][next][first][last][top][bottom][index][help] */
 834 {
 835     for( ; *str; ++str ) {
 836         if (*str == '\n')
 837             ata_mfp_out( '\r' );
 838         ata_mfp_out( *str );
 839     }
 840 }
 841 
 842 static inline void ata_scc_out (char c)
     /* [previous][next][first][last][top][bottom][index][help] */
 843 {
 844     do {
 845         MFPDELAY();
 846     } while (!(scc.cha_b_ctrl & 0x04)); /* wait for tx buf empty */
 847     MFPDELAY();
 848     scc.cha_b_data = c;
 849 }
 850 
 851 void ata_scc_print (const char *str)
     /* [previous][next][first][last][top][bottom][index][help] */
 852 {
 853     for( ; *str; ++str ) {
 854         if (*str == '\n')
 855             ata_scc_out( '\r' );
 856         ata_scc_out( *str );
 857     }
 858 }
 859 
 860 static int ata_par_out (char c)
     /* [previous][next][first][last][top][bottom][index][help] */
 861 {
 862     extern unsigned long loops_per_sec;
 863     unsigned char tmp;
 864     /* This a some-seconds timeout in case no printer is connected */
 865     unsigned long i = loops_per_sec > 1 ? loops_per_sec : 10000000;
 866 
 867     while( (mfp.par_dt_reg & 1) && --i ) /* wait for BUSY == L */
 868         ;
 869     if (!i) return( 0 );
 870     
 871     sound_ym.rd_data_reg_sel = 15;  /* select port B */
 872     sound_ym.wd_data = c;           /* put char onto port */
 873     sound_ym.rd_data_reg_sel = 14;  /* select port A */
 874     tmp = sound_ym.rd_data_reg_sel;
 875     sound_ym.wd_data = tmp & ~0x20; /* set strobe L */
 876     MFPDELAY();                     /* wait a bit */
 877     sound_ym.wd_data = tmp | 0x20;  /* set strobe H */
 878     return( 1 );
 879 }
 880 
 881 void ata_par_print (const char *str)
     /* [previous][next][first][last][top][bottom][index][help] */
 882 {
 883     static int printer_present = 1;
 884 
 885     if (!printer_present)
 886         return;
 887 
 888     for( ; *str; ++str ) {
 889         if (*str == '\n')
 890             if (!ata_par_out( '\r' )) {
 891                 printer_present = 0;
 892                 return;
 893             }
 894         if (!ata_par_out( *str )) {
 895             printer_present = 0;
 896             return;
 897         }
 898     }
 899 }
 900 
 901 
 902 void atari_debug_init( void )
     /* [previous][next][first][last][top][bottom][index][help] */
 903 {
 904     extern void (*debug_print_proc)(const char *);
 905     extern char m68k_debug_device[];
 906     
 907     if (!strcmp( m68k_debug_device, "ser" )) {
 908         /* defaults to ser2 for a Falcon and ser1 otherwise */
 909         strcpy( m68k_debug_device, 
 910                 ((boot_info.bi_atari.mch_cookie >> 16) == ATARI_MCH_FALCON) ?
 911                 "ser2" : "ser1" );
 912 
 913     }
 914 
 915     if (!strcmp( m68k_debug_device, "ser1" )) {
 916         /* ST-MFP Modem1 serial port */
 917         mfp.trn_stat  &= ~0x01; /* disable TX */
 918         mfp.usart_ctr  = 0x88;  /* clk 1:16, 8N1 */
 919         mfp.tim_ct_cd &= 0x70;  /* stop timer D */
 920         mfp.tim_dt_d   = 2;     /* 9600 bps */
 921         mfp.tim_ct_cd |= 0x01;  /* start timer D, 1:4 */
 922         mfp.trn_stat  |= 0x01;  /* enable TX */
 923         debug_print_proc = ata_mfp_print;
 924     }
 925     else if (!strcmp( m68k_debug_device, "ser2" )) {
 926         /* SCC Modem2 serial port */
 927         static unsigned char *p, scc_table[] = {
 928             9, 12,              /* Reset */
 929             4, 0x44,            /* x16, 1 stopbit, no parity */
 930             3, 0xc0,            /* receiver: 8 bpc */
 931             5, 0xe2,            /* transmitter: 8 bpc, assert dtr/rts */
 932             9, 0,               /* no interrupts */
 933             10, 0,              /* NRZ */
 934             11, 0x50,           /* use baud rate generator */
 935             12, 24, 13, 0,      /* 9600 baud */
 936             14, 2, 14, 3,       /* use master clock for BRG, enable */
 937             3, 0xc1,            /* enable receiver */
 938             5, 0xea,            /* enable transmitter */
 939             0
 940         };
 941             
 942         (void)scc.cha_b_ctrl; /* reset reg pointer */
 943         for( p = scc_table; *p != 0; ) {
 944             scc.cha_b_ctrl = *p++;
 945             MFPDELAY();
 946             scc.cha_b_ctrl = *p++;
 947             MFPDELAY();
 948         }
 949         debug_print_proc = ata_scc_print;
 950     }
 951     else if (!strcmp( m68k_debug_device, "par" )) {
 952         /* parallel printer */
 953         atari_turnoff_irq( IRQ_MFP_BUSY ); /* avoid ints */
 954         sound_ym.rd_data_reg_sel = 7;  /* select mixer control */
 955         sound_ym.wd_data = 0xff;       /* sound off, ports are output */
 956         sound_ym.rd_data_reg_sel = 15; /* select port B */
 957         sound_ym.wd_data = 0;          /* no char */
 958         sound_ym.rd_data_reg_sel = 14; /* select port A */
 959         sound_ym.wd_data = sound_ym.rd_data_reg_sel | 0x20; /* strobe H */
 960         debug_print_proc = ata_par_print;
 961     }
 962     else
 963         debug_print_proc = NULL;
 964 }
 965 
 966 
 967 void ata_serial_print (const char *str)
     /* [previous][next][first][last][top][bottom][index][help] */
 968 {
 969   int c;
 970 
 971   while (c = *str++, c != 0)
 972     {
 973       if (c == '\n')
 974         {
 975           while (!(mfp.trn_stat & (1 << 7)))
 976             barrier ();
 977           mfp.usart_dta = '\r';
 978         }
 979       while (!(mfp.trn_stat & (1 << 7)))
 980         barrier ();
 981       mfp.usart_dta = c;
 982     }
 983 }
 984 
 985 /* ++roman:
 986  *
 987  * This function does a reset on machines that lack the ability to
 988  * assert the processor's _RESET signal somehow via hardware. It is
 989  * based on the fact that you can find the initial SP and PC values
 990  * after a reset at physical addresses 0 and 4. This works pretty well
 991  * for Atari machines, since the lowest 8 bytes of physical memory are
 992  * really ROM (mapped by hardware). For other 680x0 machines: don't
 993  * know if it works...
 994  *
 995  * To get the values at addresses 0 and 4, the MMU better is turned
 996  * off first. After that, we have to jump into physical address space
 997  * (the PC before the pmove statement points to the virtual address of
 998  * the code). Getting that physical address is not hard, but the code
 999  * becomes a bit complex since I've tried to ensure that the jump
1000  * statement after the pmove is in the cache already (otherwise the
1001  * processor can't fetch it!). For that, the code first jumps to the
1002  * jump statement with the (virtual) address of the pmove section in
1003  * an address register . The jump statement is surely in the cache
1004  * now. After that, that physical address of the reset code is loaded
1005  * into the same address register, pmove is done and the same jump
1006  * statements goes to the reset code. Since there are not many
1007  * statements between the two jumps, I hope it stays in the cache.
1008  *
1009  * The C code makes heavy use of the GCC features that you can get the
1010  * address of a C label. No hope to compile this with another compiler
1011  * than GCC!
1012  */
1013   
1014 /* ++andreas: no need for complicated code, just depend on prefetch */
1015 
1016 void atari_reset (void)
     /* [previous][next][first][last][top][bottom][index][help] */
1017 {
1018     long tc_val = 0;
1019     long reset_addr;
1020 
1021     /* On the Medusa, phys. 0x4 may contain garbage because it's no
1022        ROM.  See above for explanation why we cannot use PTOV(4). */
1023     reset_addr = is_medusa ? 0xe00030 : *(unsigned long *) 0xff000004;
1024 
1025     acia.key_ctrl = ACIA_RESET;             /* reset ACIA for switch off OverScan, if it's active */
1026 
1027     /* processor independent: turn off interrupts and reset the VBR;
1028      * the caches must be left enabled, else prefetching the final jump
1029      * instruction doesn't work. */
1030     cli();
1031     __asm__ __volatile__
1032         ("moveq #0,%/d0\n\t"
1033          "movec %/d0,%/vbr"
1034          : : : "d0" );
1035     
1036     if (m68k_is040or060) {
1037         unsigned long jmp_addr040 = VTOP(&&jmp_addr_label040);
1038         if (m68k_is040or060 == 6) {
1039             /* 68060: clear PCR to turn off superscalar operation */
1040             __asm__ __volatile__
1041                 ("moveq #0,%/d0\n\t"
1042                  ".long 0x4e7b0808"     /* movec d0,pcr */
1043                  : : : "d0" );
1044         }
1045             
1046         __asm__ __volatile__
1047             ("movel    %0,%/d0\n\t"
1048              "andl     #0xff000000,%/d0\n\t"
1049              "orw      #0xe020,%/d0\n\t"   /* map 16 MB, enable, cacheable */
1050              ".long    0x4e7b0004\n\t"   /* movec d0,itt0 */
1051              ".long    0x4e7b0006\n\t"   /* movec d0,dtt0 */
1052              "jmp   %0@\n\t"
1053              : /* no outputs */
1054              : "a" (jmp_addr040)
1055              : "d0" );
1056       jmp_addr_label040:
1057         __asm__ __volatile__
1058           ("moveq #0,%/d0\n\t"
1059            ".word 0xf4d8\n\t"           /* cinva i/d */
1060            ".word 0xf518\n\t"           /* pflusha */
1061            ".long 0x4e7b0003\n\t"       /* movec d0,tc */
1062            "jmp %0@"
1063            : /* no outputs */
1064            : "a" (reset_addr)
1065            : "d0");
1066     }
1067     else
1068         __asm__ __volatile__
1069             ("pmove %0@,%/tc\n\t"
1070              "jmp %1@"
1071              : /* no outputs */
1072              : "a" (&tc_val), "a" (reset_addr));
1073 }
1074 
1075 
1076 void atari_get_model(char *model)
     /* [previous][next][first][last][top][bottom][index][help] */
1077 {
1078     strcpy(model, "Atari ");
1079     switch (boot_info.bi_atari.mch_cookie >> 16) {
1080         case ATARI_MCH_ST:
1081             if (ATARIHW_PRESENT(MSTE_CLK))
1082                 strcat (model, "Mega ST");
1083             else
1084                 strcat (model, "ST");
1085             break;
1086         case ATARI_MCH_STE:
1087             if ((boot_info.bi_atari.mch_cookie & 0xffff) == 0x10)
1088                 strcat (model, "Mega STE");
1089             else
1090                 strcat (model, "STE");
1091             break;
1092         case ATARI_MCH_TT:
1093             if (is_medusa)
1094                 /* Medusa has TT _MCH cookie */
1095                 strcat (model, "Medusa");
1096             else
1097                 strcat (model, "TT");
1098             break;
1099         case ATARI_MCH_FALCON:
1100             strcat (model, "Falcon");
1101             break;
1102         default:
1103             sprintf (model + strlen (model), "(unknown mach cookie 0x%lx)",
1104                      boot_info.bi_atari.mch_cookie);
1105             break;
1106     }
1107 }
1108 
1109 
1110 int atari_get_hardware_list(char *buffer)
     /* [previous][next][first][last][top][bottom][index][help] */
1111 {
1112     int len = 0;
1113 
1114     for (i = 0; i < boot_info.num_memory; i++)
1115         len += sprintf (buffer+len, "\t%3ld MB at 0x%08lx (%s)\n",
1116                         boot_info.memory[i].size >> 20,
1117                         boot_info.memory[i].addr,
1118                         (boot_info.memory[i].addr & 0xff000000 ?
1119                          "alternate RAM" : "ST-RAM"));
1120 
1121 #define ATARIHW_ANNOUNCE(name,str)                              \
1122     if (ATARIHW_PRESENT(name))                  \
1123         len += sprintf (buffer + len, "\t%s\n", str)
1124 
1125     len += sprintf (buffer + len, "Detected hardware:\n");
1126     ATARIHW_ANNOUNCE(STND_SHIFTER, "ST Shifter");
1127     ATARIHW_ANNOUNCE(EXTD_SHIFTER, "STe Shifter");
1128     ATARIHW_ANNOUNCE(TT_SHIFTER, "TT Shifter");
1129     ATARIHW_ANNOUNCE(VIDEL_SHIFTER, "Falcon Shifter");
1130     ATARIHW_ANNOUNCE(YM_2149, "Programmable Sound Generator");
1131     ATARIHW_ANNOUNCE(PCM_8BIT, "PCM 8 Bit Sound");
1132     ATARIHW_ANNOUNCE(CODEC, "CODEC Sound");
1133     ATARIHW_ANNOUNCE(TT_SCSI, "SCSI Controller NCR5380 (TT style)");
1134     ATARIHW_ANNOUNCE(ST_SCSI, "SCSI Controller NCR5380 (Falcon style)");
1135     ATARIHW_ANNOUNCE(ACSI, "ACSI Interface");
1136     ATARIHW_ANNOUNCE(IDE, "IDE Interface");
1137     ATARIHW_ANNOUNCE(FDCSPEED, "8/16 Mhz Switch for FDC");
1138     ATARIHW_ANNOUNCE(ST_MFP, "Multi Function Peripheral MFP 68901");
1139     ATARIHW_ANNOUNCE(TT_MFP, "Second Multi Function Peripheral MFP 68901");
1140     ATARIHW_ANNOUNCE(SCC, "Serial Communications Controller SCC 8530");
1141     ATARIHW_ANNOUNCE(ST_ESCC, "Extended Serial Communications Controller SCC 85230");
1142     ATARIHW_ANNOUNCE(ANALOG_JOY, "Paddle Interface");
1143     ATARIHW_ANNOUNCE(MICROWIRE, "MICROWIRE(tm) Interface");
1144     ATARIHW_ANNOUNCE(STND_DMA, "DMA Controller (24 bit)");
1145     ATARIHW_ANNOUNCE(EXTD_DMA, "DMA Controller (32 bit)");
1146     ATARIHW_ANNOUNCE(SCSI_DMA, "DMA Controller for NCR5380");
1147     ATARIHW_ANNOUNCE(SCC_DMA, "DMA Controller for SCC");
1148     ATARIHW_ANNOUNCE(TT_CLK, "Clock Chip MC146818A");
1149     ATARIHW_ANNOUNCE(MSTE_CLK, "Clock Chip RP5C15");
1150     ATARIHW_ANNOUNCE(SCU, "System Control Unit");
1151     ATARIHW_ANNOUNCE(BLITTER, "Blitter");
1152     ATARIHW_ANNOUNCE(VME, "VME Bus");
1153 
1154     return(len);
1155 }

/* [previous][next][first][last][top][bottom][index][help] */