From: Roman.Hodek@informatik.uni-erlangen.de (Roman Hodek)
Date: Sat, 29 Nov 1997 00:58:02 +0100 (CET)
To: linux-m68k@lists.linux-m68k.org
Subject: L68K: Again a few patches
Sender: owner-linux-m68k@phil.uni-sb.de


Results of that last few days:

 - There's a new Atari-specific command line option: switches=
   Its purpose is to activate some hardware lines to enable/disable
   misc hardware extensions, like e.g. OverScan, overclocking, ...

   Formerly enabling of OverScan was done with video=atafb:sw_acia or
   similar options, but these 1) were active only if the also was a
   video=internal: and 2) the switching needs not be related to
   OverScan or video at all. So I tried to make that more systematic.

   The value after switches= is a comma-separated listed of switch
   lines. Currently available are "ikbd", "midi", "snd6", and "snd6".
   The first two stand for setting the RTS line of the appropriate
   ACIA to high instead of low. The switches= options is parsed and
   executed very early in the boot process, so that these hardware
   extensions aren't enabled too late.

   All the suboptions can also be prefixed with "ov_" to flag that
   they're meant for turning on OverScan. The difference to the plain
   option is that the switch is done later, after video
   initialization, and with some synchronization to the HBLANK. Also
   the switch is disabled before resetting the machine, so that TOS
   can boot correctly.

   See also Documentation/m68k/kernel-options.txt for more infos. If
   you were using sw_acia, sw_snd6, or sw_snd6 in your video= option,
   please rewrite this to switches=.

 - Implement check for FPU and panic if none is present.

 - Deleted KEYB_WRITE_INTERRUPT conditional parts in atakeyb.c --
   they're unused and won't be used and just clutter up the code.

 - Now also "midi" is possible as debug device and as serial console
   (/dev/ttyS5). It complies, but it's untested (I don't have a
   receiver for it...)

 - atari/stram.c didn't compile without CONFIG_STRAM_SWAP defined,
   because some definitions were inside #ifdefs.

 - If ST-RAM swapping is enabled, also correct 'num_physpages'
   (subtract number of swap pages).

 - Remove _BHA_MIDI_SHADOW #ifdefs in atari_MIDI.c -- shadowing is
   always necessary.

Roman

------------------------------------------------------------------------------
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.64.orig/Documentation/m68k/kernel-options.txt linux-2.1.64/Documentation/m68k/kernel-options.txt
--- linux-2.1.64.orig/Documentation/m68k/kernel-options.txt	Mon Nov 17 22:54:48 1997
+++ linux-2.1.64/Documentation/m68k/kernel-options.txt	Fri Nov 28 14:11:18 1997
@@ -3,8 +3,8 @@
 				  Command Line Options for Linux/m68k
 				  ===================================
 
-Date: Oct 6, 1997
-Linux/m68k version: 2.0.21
+Last Update: Nov 28, 1997
+Linux/m68k version: 2.1.64
 Author: Roman.Hodek@informatik.uni-erlangen.de (Roman Hodek)
 Update: jds@kom.auc.dk (Jes Sorensen)
 
@@ -191,6 +191,7 @@
  - "ser2": SCC channel B serial port ("Modem2"); parameters: 9600bps, 8N1
  - "ser" : default serial port
            This is "ser2" for a Falcon, and "ser1" for any other machine
+ - "midi": The MIDI port; parameters: 31250bps, 8N1
  - "par" : parallel port
            The printing routine for this implements a timeout for the
            case there's no printer connected (else the kernel would
@@ -408,19 +409,7 @@
   Often, extended interval video hardware has to be activated somehow.
 For this, see the "sw_*" options below.
 
-4.1.6) sw_acia, sw_snd6, sw_snd7
---------------------------------
-
-This specifies the method for turning on extended internal video
-hardware, like OverScan. Several methods are in use:
-
-  sw_acia: Set RTS of the keyboard ACIA high
-  sw_snd6: Set bit 6 of the PSG port A
-  sw_snd7: Set bit 7 of the PSG port A
-
-These sub-options are generally only useful together with "internal:".
-
-4.1.7) external:
+4.1.6) external:
 ----------------
 
 Syntax:
@@ -509,13 +498,13 @@
 therefore we don't support hardware-dependend functions like hardware-scroll,
 panning or blanking.
 
-4.1.8) eclock:
+4.1.7) eclock:
 --------------
 
 The external pixel clock attached to the Falcon VIDEL shifter. This
 currently works only with the ScreenWonder!
 
-4.1.9) monitorcap:
+4.1.8) monitorcap:
 -------------------
 
 Syntax: monitorcap:<vmin>;<vmax>;<hmin>;<hmax>
@@ -532,7 +521,7 @@
 
   The defaults for TV/SC1224/SC1435 cover both PAL and NTSC standards.
 
-4.1.10) keep
+4.1.9) keep
 ------------
 
 If this option is given, the framebuffer device doesn't do any video
@@ -671,6 +660,41 @@
 you want to use parts of ST-RAM as normal system memory. <max_swap> is
 in kBytes and the number should be a multiple of 4 (otherwise: rounded
 down).
+
+4.6 switches=
+-------------
+
+Syntax: switches=<list of switches>
+
+  With this option you can switch some hardware lines that are often
+used to enable/disable certain hardware extensions. Examples are
+OverScan, overclocking, ...
+
+  The <list of switches> is a comma-separated list of the following
+items:
+
+  ikbd: set RTS of the keyboard ACIA high
+  midi: set RTS of the MIDI ACIA high
+  snd6: set bit 6 of the PSG port A
+  snd7: set bit 6 of the PSG port A
+
+It doesn't make sense to mention a switch more than once (no
+difference to only once), but you can give as many switches as you
+want to enable different features. The switch lines are set as early
+as possible during kernel initialization (even before determining the
+present hardware.)
+
+  All of the items can also be prefixed with "ov_", i.e. "ov_ikbd",
+"ov_midi", ... These options are meant for switching on an OverScan
+video extension. The difference to the bare option is that the
+switch-on is done after video initialization, and somehow synchronized
+to the HBLANK. A speciality is that ov_ikbd and ov_midi are switched
+off before rebooting, so that OverScan is disabled and TOS boots
+correctly.
+
+  If you give an option both, with and without the "ov_" prefix, the
+earlier initialization ("ov_"-less) takes precedence. But the
+switching-off on reset still happens in this case.
 
 
 5) Options for Amiga Only:
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.64.orig/arch/m68k/atari/atakeyb.c linux-2.1.64/arch/m68k/atari/atakeyb.c
--- linux-2.1.64.orig/arch/m68k/atari/atakeyb.c	Tue Jun 17 13:38:02 1997
+++ linux-2.1.64/arch/m68k/atari/atakeyb.c	Fri Nov 28 12:07:43 1997
@@ -32,7 +32,6 @@
 #include <asm/atari_joystick.h>
 #include <asm/irq.h>
 
-extern int ovsc_switchmode;
 extern unsigned char mach_keyboard_type;
 static void atakeyb_rep( unsigned long ignore );
 extern unsigned int keymap_count;
@@ -504,23 +503,6 @@
 	}
     }
 
-#ifdef KEYB_WRITE_INTERRUPT
-    if (acia_stat & ACIA_TDRE)	/* transmit of character is finished */
-    {
-	if (kb_state.buf)
-	{
-	    acia.key_data = *kb_state.buf++;
-	    kb_state.len--;
-	    if (kb_state.len == 0)
-	    {
-		kb_state.buf = NULL;
-		if (!kb_state.kernel_mode)
-			/* unblock something */;
-	    }
-	}
-    }
-#endif
-
 #if 0
     if (acia_stat & ACIA_CTS)
 	/* cannot happen */;
@@ -537,26 +519,6 @@
     goto repeat;
 }
 
-#ifdef KEYB_WRITE_INTERRUPT
-void ikbd_write(const char *str, int len)
-{
-    u_char acia_stat;
-
-    if (kb_stat.buf)
-	/* wait */;
-    acia_stat = acia.key_ctrl;
-    if (acia_stat & ACIA_TDRE)
-    {
-	if (len != 1)
-	{
-	    kb_stat.buf = str + 1;
-	    kb_stat.len = len - 1;
-	}
-	acia.key_data = *str;
-	/* poll */
-    }
-}
-#else
 /*
  * I write to the keyboard without using interrupts, I poll instead.
  * This takes for the maximum length string allowed (7) at 7812.5 baud
@@ -581,7 +543,6 @@
 	}
     }
 }
-#endif
 
 /* Reset (without touching the clock) */
 void ikbd_reset(void)
@@ -828,33 +789,28 @@
 
     atari_turnoff_irq(IRQ_MFP_ACIA);
     do {
-	acia.key_ctrl = ACIA_RESET;		/* reset ACIA */
+	/* reset IKBD ACIA */
+	acia.key_ctrl = ACIA_RESET |
+			(atari_switches & ATARI_SWITCH_IKBD) ? ACIA_RHTID : 0;
 	(void)acia.key_ctrl;
 	(void)acia.key_data;
 
-	acia.mid_ctrl = ACIA_RESET;		/* reset other ACIA */
+	/* reset MIDI ACIA */
+	acia.mid_ctrl = ACIA_RESET |
+			(atari_switches & ATARI_SWITCH_MIDI) ? ACIA_RHTID : 0;
 	(void)acia.mid_ctrl;
 	(void)acia.mid_data;
 
 	/* divide 500kHz by 64 gives 7812.5 baud */
 	/* 8 data no parity 1 start 1 stop bit */
 	/* receive interrupt enabled */
-#ifdef KEYB_WRITE_INTERRUPT
-	/* RTS low, transmit interrupt enabled */
-	if (ovsc_switchmode == 1)
-	    acia.key_ctrl = (ACIA_DIV64|ACIA_D8N1S|ACIA_RHTIE|ACIA_RIE);
-	    /* switch on OverScan via keyboard ACIA */
-	else
-	    acia.key_ctrl = (ACIA_DIV64|ACIA_D8N1S|ACIA_RLTIE|ACIA_RIE);
-#else
-	/* RTS low, transmit interrupt disabled */
-	if (ovsc_switchmode == 1)
-	    acia.key_ctrl = (ACIA_DIV64|ACIA_D8N1S|ACIA_RHTID|ACIA_RIE);
-	else
-	    acia.key_ctrl = (ACIA_DIV64|ACIA_D8N1S|ACIA_RLTID|ACIA_RIE);
-#endif
+	/* RTS low (except if switch selected), transmit interrupt disabled */
+	acia.key_ctrl = (ACIA_DIV64|ACIA_D8N1S|ACIA_RIE) |
+			((atari_switches & ATARI_SWITCH_IKBD) ?
+			 ACIA_RHTID : ACIA_RLTID);
 	   
-	acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S;
+	acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S |
+			(atari_switches & ATARI_SWITCH_MIDI) ? ACIA_RHTID : 0;
     }
     /* make sure the interrupt line is up */
     while ((mfp.par_dt_reg & 0x10) == 0);
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.64.orig/arch/m68k/atari/atari_ksyms.c linux-2.1.64/arch/m68k/atari/atari_ksyms.c
--- linux-2.1.64.orig/arch/m68k/atari/atari_ksyms.c	Sat Nov 22 01:08:08 1997
+++ linux-2.1.64/arch/m68k/atari/atari_ksyms.c	Fri Nov 28 13:31:23 1997
@@ -17,6 +17,7 @@
 EXPORT_SYMBOL(atari_mch_cookie);
 EXPORT_SYMBOL(atari_mch_type);
 EXPORT_SYMBOL(atari_hw_present);
+EXPORT_SYMBOL(atari_switches);
 EXPORT_SYMBOL(atari_register_vme_int);
 EXPORT_SYMBOL(atari_unregister_vme_int);
 EXPORT_SYMBOL(stdma_lock);
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.64.orig/arch/m68k/atari/config.c linux-2.1.64/arch/m68k/atari/config.c
--- linux-2.1.64.orig/arch/m68k/atari/config.c	Fri Nov 21 22:18:51 1997
+++ linux-2.1.64/arch/m68k/atari/config.c	Fri Nov 28 23:49:59 1997
@@ -54,6 +54,7 @@
 u_long atari_mch_cookie;
 u_long atari_mch_type = 0;
 struct atari_hw_present atari_hw_present;
+u_long atari_switches = 0;
 int atari_rtc_year_offset;
 
 extern char m68k_debug_device[];
@@ -261,6 +262,45 @@
     return(unknown);
 }
 
+
+/* Parse the Atari-specific switches= option. */
+__initfunc(void atari_switches_setup( const char *str, unsigned len ))
+{
+    char switches[len+1];
+    char *p;
+    int ovsc_shift;
+
+    /* copy string to local array, strtok works destructively... */
+    strncpy( switches, str, len );
+    switches[len] = 0;
+    atari_switches = 0;
+
+    /* parse the options */
+    for( p = strtok( switches, "," ); p; p = strtok( NULL, "," ) ) {
+	ovsc_shift = 0;
+	if (strncmp( p, "ov_", 3 ) == 0) {
+	    p += 3;
+	    ovsc_shift = ATARI_SWITCH_OVSC_SHIFT;
+	}
+	
+	if (strcmp( p, "ikbd" ) == 0) {
+	    /* RTS line of IKBD ACIA */
+	    atari_switches |= ATARI_SWITCH_IKBD << ovsc_shift;
+	}
+	else if (strcmp( p, "midi" ) == 0) {
+	    /* RTS line of MIDI ACIA */
+	    atari_switches |= ATARI_SWITCH_MIDI << ovsc_shift;
+	}
+	else if (strcmp( p, "snd6" ) == 0) {
+	    atari_switches |= ATARI_SWITCH_SND6 << ovsc_shift;
+	}
+	else if (strcmp( p, "snd7" ) == 0) {
+	    atari_switches |= ATARI_SWITCH_SND7 << ovsc_shift;
+	}
+    }
+}
+
+
     /*
      *  Setup the Atari configuration info
      */
@@ -294,12 +334,24 @@
     mach_max_dma_address = 0xffffff;
     kd_mksound		 = atari_mksound;
 #ifdef CONFIG_MAGIC_SYSRQ
-	mach_sysrq_key = 98;          /* HELP */
-	mach_sysrq_shift_state = 8;   /* Alt */
-	mach_sysrq_shift_mask = 0xff; /* all modifiers except CapsLock */
-	mach_sysrq_xlate = atari_sysrq_xlate;
+    mach_sysrq_key = 98;          /* HELP */
+    mach_sysrq_shift_state = 8;   /* Alt */
+    mach_sysrq_shift_mask = 0xff; /* all modifiers except CapsLock */
+    mach_sysrq_xlate = atari_sysrq_xlate;
 #endif
 
+    /* Set switches as requested by the user */
+    if (atari_switches & ATARI_SWITCH_IKBD)
+	acia.key_ctrl = ACIA_DIV64 | ACIA_D8N1S | ACIA_RHTID;
+    if (atari_switches & ATARI_SWITCH_MIDI)
+	acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S | ACIA_RHTID;
+    if (atari_switches & (ATARI_SWITCH_SND6|ATARI_SWITCH_SND7)) {
+	sound_ym.rd_data_reg_sel = 14;
+	sound_ym.wd_data = sound_ym.rd_data_reg_sel |
+			   ((atari_switches&ATARI_SWITCH_SND6) ? 0x40 : 0) |
+			   ((atari_switches&ATARI_SWITCH_SND7) ? 0x80 : 0);
+    }
+	
     /* ++bjoern: 
      * Determine hardware present
      */
@@ -931,7 +983,6 @@
 }
 
 
-
 static inline void ata_mfp_out (char c)
 {
     while (!(mfp.trn_stat & 0x80)) /* wait for tx buf empty */
@@ -966,6 +1017,22 @@
     }
 }
 
+static inline void ata_midi_out (char c)
+{
+    while (!(acia.mid_ctrl & ACIA_TDRE)) /* wait for tx buf empty */
+	barrier ();
+    acia.mid_data = c;
+}
+
+void atari_midi_console_write (const char *str, unsigned int count)
+{
+    while (count--) {
+	if (*str == '\n')
+	    ata_midi_out( '\r' );
+	ata_midi_out( *str++ );
+    }
+}
+
 static int ata_par_out (char c)
 {
     unsigned char tmp;
@@ -1022,6 +1089,13 @@
     MFPDELAY();
     return( scc.cha_b_data );
 }
+
+int atari_midi_console_wait_key(void)
+{
+    while( !(acia.mid_ctrl & ACIA_RDRF) ) /* wait for rx buf filled */
+	barrier();
+    return( acia.mid_data );
+}
 #endif
 
 /* The following two functions do a quick'n'dirty initialization of the MFP or
@@ -1141,12 +1215,41 @@
     atari_SCC_init_done = 1;
 }
 
+#ifndef CONFIG_SERIAL_CONSOLE 
+__initfunc(static void atari_init_midi_port( int cflag ))
+#else
+void atari_init_midi_port( int cflag )
+#endif
+{
+    int baud = cflag & CBAUD;
+    int csize = ((cflag & CSIZE) == CS8) ? 0x10 : 0x00;
+    /* warning 7N1 isn't possible! (instead 7O2 is used...) */
+    int parity = (cflag & PARENB) ? ((cflag & PARODD) ? 0x0c : 0x08) : 0x04;
+    int div;
+
+    /* 4800 selects 7812.5, 115200 selects 500000, all other (incl. 9600 as
+     * default) the standard MIDI speed 31250. */
+    if (cflag & CBAUDEX)
+	baud += B38400;
+    if (baud == B4800)
+	div = ACIA_DIV64; /* really 7812.5 bps */
+    else if (baud == B38400+2 /* 115200 */)
+	div = ACIA_DIV1; /* really 500 kbps (does that work??) */
+    else
+	div = ACIA_DIV16; /* 31250 bps, standard for MIDI */
+
+    /* RTS low, ints disabled */
+    acia.mid_ctrl = div | csize | parity |
+		    ((atari_switches & ATARI_SWITCH_MIDI) ?
+		     ACIA_RHTID : ACIA_RLTID);
+}
+
 __initfunc(static void atari_debug_init(void))
 {
 #ifdef CONFIG_KGDB
     /* the m68k_debug_device is used by the GDB stub, do nothing here */
     return;
-#else
+#endif
     if (!strcmp( m68k_debug_device, "ser" )) {
 	/* defaults to ser2 for a Falcon and ser1 otherwise */
 	strcpy( m68k_debug_device, MACH_IS_FALCON ? "ser2" : "ser1" );
@@ -1162,6 +1265,11 @@
 	atari_init_scc_port( B9600|CS8 );
 	atari_console_driver.write = atari_scc_console_write;
     }
+    else if (!strcmp( m68k_debug_device, "midi" )) {
+	/* MIDI port */
+	atari_init_scc_port( B9600|CS8 );
+	atari_console_driver.write = atari_midi_console_write;
+    }
     else if (!strcmp( m68k_debug_device, "par" )) {
 	/* parallel printer */
 	atari_turnoff_irq( IRQ_MFP_BUSY ); /* avoid ints */
@@ -1175,7 +1283,6 @@
     }
     if (atari_console_driver.write)
 	register_console(&atari_console_driver);
-#endif
 }
 
 /* ++roman:
@@ -1220,8 +1327,12 @@
                  MACH_IS_MEDUSA || MACH_IS_AB40 ? 0xe00030 :
 		 *(unsigned long *) 0xff000004;
 
-    acia.key_ctrl = ACIA_RESET;             /* reset ACIA for switch off OverScan, if it's active */
-
+    /* reset ACIA for switch off OverScan, if it's active */
+    if (atari_switches & ATARI_SWITCH_OVSC_IKBD)
+	acia.key_ctrl = ACIA_RESET;
+    if (atari_switches & ATARI_SWITCH_OVSC_MIDI)
+	acia.mid_ctrl = ACIA_RESET;
+    
     /* processor independent: turn off interrupts and reset the VBR;
      * the caches must be left enabled, else prefetching the final jump
      * instruction doesn't work. */
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.64.orig/arch/m68k/atari/stram.c linux-2.1.64/arch/m68k/atari/stram.c
--- linux-2.1.64.orig/arch/m68k/atari/stram.c	Fri Nov 28 23:49:52 1997
+++ linux-2.1.64/arch/m68k/atari/stram.c	Fri Nov 28 23:46:49 1997
@@ -150,23 +150,6 @@
 /* set if kernel is in ST-RAM */
 static int kernel_in_stram;
 
-#ifdef CONFIG_STRAM_SWAP
-/* max. number of bytes to use for swapping
- *  0 = no ST-RAM swapping
- * -1 = do swapping (to whole ST-RAM) if it's less than MAX_STRAM_FRACTION of
- *      total memory
- */
-static int max_swap_size = -1;
-
-/* start and end of swapping area */
-static unsigned long swap_start, swap_end;
-
-/* The ST-RAM's swap info structure */
-static struct swap_info_struct *stram_swap_info;
-
-/* The ST-RAM's swap type */
-static int stram_swap_type;
-
 typedef struct stram_block {
 	struct stram_block *next;
 	unsigned long start;
@@ -192,6 +175,23 @@
 #define N_STATIC_BLOCKS	20
 static BLOCK static_blocks[N_STATIC_BLOCKS];
 
+#ifdef CONFIG_STRAM_SWAP
+/* max. number of bytes to use for swapping
+ *  0 = no ST-RAM swapping
+ * -1 = do swapping (to whole ST-RAM) if it's less than MAX_STRAM_FRACTION of
+ *      total memory
+ */
+static int max_swap_size = -1;
+
+/* start and end of swapping area */
+static unsigned long swap_start, swap_end;
+
+/* The ST-RAM's swap info structure */
+static struct swap_info_struct *stram_swap_info;
+
+/* The ST-RAM's swap type */
+static int stram_swap_type;
+
 /* major and minor device number of the ST-RAM device; for the major, we use
  * the same as Amiga z2ram, which is really similar and impossible on Atari,
  * and for the minor a relatively odd number to avoid the user creating and
@@ -396,6 +396,12 @@
 		 * You just will get non-DMA-able memory...
 		 */
 		mach_max_dma_address = 0xffffffff;
+
+		/*
+		 * Ok, num_physpages needs not be really exact, but it's better to
+		 * subtract the pages set aside for swapping.
+		 */
+		num_physpages -= SWAP_NR(swap_end)-1;
 	}
 #endif
 	
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.64.orig/arch/m68k/kernel/setup.c linux-2.1.64/arch/m68k/kernel/setup.c
--- linux-2.1.64.orig/arch/m68k/kernel/setup.c	Sat Nov  1 19:01:23 1997
+++ linux-2.1.64/arch/m68k/kernel/setup.c	Thu Nov 27 17:36:22 1997
@@ -191,6 +191,15 @@
 		if ((q = strchr( m68k_debug_device, ' ' ))) *q = 0;
 		i = 1;
 	    }
+#ifdef CONFIG_ATARI
+	    /* This option must be parsed very early */
+	    if (!strncmp( p, "switches=", 9 )) {
+		extern void atari_switches_setup( const char *, int );
+		atari_switches_setup( p+9, (q = strchr( p+9, ' ' )) ?
+				           (q - (p+9)) : strlen(p+9) );
+		i = 1;
+	    }
+#endif
 
 	    if (i) {
 		/* option processed, delete it */
@@ -366,4 +375,18 @@
 		mach_gettod(year, mon, day, hour, min, sec);
 	else
 		*year = *mon = *day = *hour = *min = *sec = 0;
+}
+
+void check_bugs(void)
+{
+#ifndef CONFIG_FPU_EMU
+	if (m68k_fputype == 0) {
+		printk( KERN_EMERG "*** YOU DO NOT HAVE A FLOATING POINT UNIT, "
+				"WHICH IS REQUIRED BY LINUX/M68K ***\n" );
+		printk( KERN_EMERG "Upgrade your hardware or join the FPU "
+				"emulation project\n" );
+		printk( KERN_EMERG "(see http://no-fpu.linux-m68k.org)\n" );
+		panic( "no FPU" );
+	}
+#endif
 }
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.64.orig/drivers/char/atari_MIDI.c linux-2.1.64/drivers/char/atari_MIDI.c
--- linux-2.1.64.orig/drivers/char/atari_MIDI.c	Fri Oct 31 19:13:40 1997
+++ linux-2.1.64/drivers/char/atari_MIDI.c	Fri Nov 28 14:00:42 1997
@@ -35,8 +35,6 @@
 
 /* #define _DEBUG_MIDI_ */
 
-#define _BHA_MIDI_SHADOW
-
 #define DEFAULT_MIDI_LINE       5          /* ttyS5 */
 #define MIDI_BAUD_BASE          500000     /* 31250 */
 
@@ -210,8 +208,12 @@
   /* Tx_err interrupt unused (it signals only that the Tx shift reg
    * is empty)
    */
-
-  	mid_ctrl_shadow = ACIA_DIV16 | ACIA_D8N1S;
+  /* Leave RTS high for now if selected as a switch, so that it's still valid
+   * as long as the port isn't opened.
+   */
+  	mid_ctrl_shadow = ACIA_DIV16 | ACIA_D8N1S |
+			  ((atari_switches&ATARI_SWITCH_MIDI) ?
+			   ACIA_RHTID : ACIA_RLTID);
   	acia.mid_ctrl = mid_ctrl_shadow;
 
   	atari_MIDI_interrupt_hook = MIDI_int;
@@ -245,13 +247,10 @@
 		}
 
 		if (ch == -1 || rs_no_more_tx( midi_info )) {
-			/* disable tx interrupts    %x01xxxxx ==> %x00xxxxx          */
-			mid_ctrl_shadow &= ~ACIA_RLTIE;  /* RTS Low, Tx IRQ Disabled */
-#ifdef _BHA_MIDI_SHADOW
+			/* disable tx interrupts    %x01xxxxx ==> %x00xxxxx */
+			/* RTS Low, Tx IRQ Disabled */
+			mid_ctrl_shadow &= ~ACIA_RLTIE;
 			acia.mid_ctrl = mid_ctrl_shadow;
-#else
-			acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S | ACIA_RIE;
-#endif
 			/* printk("T"); */
 		}
 	}
@@ -313,13 +312,9 @@
 
 		save_flags(cpu_status);
 		cli();
-		mid_ctrl_shadow |= ACIA_RLTIE;               /* RTS Low, Tx IRQ Enabled */
-
-#ifdef _BHA_MIDI_SHADOW
+		/* RTS Low, Tx IRQ Enabled */
+		mid_ctrl_shadow |= ACIA_RLTIE;
 		acia.mid_ctrl = mid_ctrl_shadow;
-#else
-		acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S | ACIA_RIE | ACIA_RLTIE;
-#endif
 		/* restarted the transmitter */
 		/* 
 		 * These extensions since 0.9.5 are only allowed, if the 
@@ -339,14 +334,10 @@
 			}
 
 			if (ch == -1 || rs_no_more_tx( midi_info )) {
-				/* disable tx interrupts */ 
-				mid_ctrl_shadow &= ~ACIA_RLTIE;         /* RTS Low, Tx IRQ Disabled */
-
-#ifdef _BHA_MIDI_SHADOW
+				/* disable tx interrupts */
+				/* RTS Low, Tx IRQ Disabled */
+				mid_ctrl_shadow &= ~ACIA_RLTIE;
 				acia.mid_ctrl = mid_ctrl_shadow;
-#else
-				acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S | ACIA_RIE;
-#endif
 
 			}
 		}
@@ -354,12 +345,9 @@
 	} else {
 		save_flags(cpu_status);
 		cli();
-		mid_ctrl_shadow &= ~ACIA_RLTIE;             /* RTS Low, Tx IRQ Disabled */
-#ifdef _BHA_MIDI_SHADOW
+		/* RTS Low, Tx IRQ Disabled */
+		mid_ctrl_shadow &= ~ACIA_RLTIE;
 		acia.mid_ctrl = mid_ctrl_shadow;
-#else
-		acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S | ACIA_RIE;
-#endif
 		restore_flags(cpu_status);
 	}
 }
@@ -553,12 +541,7 @@
 
 	/* disable receive interrupts */
 	mid_ctrl_shadow &= ~ACIA_RIE;
-
-#ifdef _BHA_MIDI_SHADOW
 	acia.mid_ctrl = mid_ctrl_shadow;
-#else
-	acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S;
-#endif
 	restore_flags(cpu_status);
 }
 
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.64.orig/drivers/char/m68kserial.c linux-2.1.64/drivers/char/m68kserial.c
--- linux-2.1.64.orig/drivers/char/m68kserial.c	Wed Nov 19 23:10:56 1997
+++ linux-2.1.64/drivers/char/m68kserial.c	Fri Nov 28 12:18:56 1997
@@ -1663,6 +1663,9 @@
 extern void atari_scc_console_write (const char *str, unsigned int count);
 extern int atari_scc_console_wait_key(void);
 extern void atari_init_scc_port( int cflag );
+extern void atari_midi_console_write (const char *str, unsigned int count);
+extern int atari_midi_console_wait_key(void);
+extern void atari_init_midi_port( int cflag );
 
 /*
  *	Setup initial baud/bits/parity.
@@ -1741,9 +1744,12 @@
 		/* amiga_init_serial_console(rs_table+sercons.index, */
 		/*			     serial_console_cflag); */
 	}
-	/* On Atari, Modem1 (ttyS0) and Modem2 (ttyS1) are supported
+	/* On Atari, Modem1 (ttyS0), Modem2 (ttyS1) and MIDI (ttyS5) are supported
 	 * Note: On a TT, 57.6 and 115.2 kbps are not possible and are replaced by
-	 * 76.8 and 153.6 kbps. */
+	 * 76.8 and 153.6 kbps.
+	 * Note2: On MIDI, 7812.5 bps is selected by 4800 on the command line, and
+	 * 500 kbps by 115200. All other rates give standard 31250bps. Mode 7N is
+	 * not possible and replaced by 7O2 ... */
 	else if (MACH_IS_ATARI && sercons.index == 0) {
 		sercons.write = atari_mfp_console_write;
 		sercons.wait_key = atari_mfp_console_wait_key;
@@ -1753,6 +1759,11 @@
 		sercons.write = atari_scc_console_write;
 		sercons.wait_key = atari_scc_console_wait_key;
 		atari_init_scc_port( cflag );
+	}
+	else if (MACH_IS_ATARI && sercons.index == 5) {
+		sercons.write = atari_midi_console_write;
+		sercons.wait_key = atari_midi_console_wait_key;
+		atari_init_midi_port( cflag );
 	}
 }
 
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.64.orig/drivers/video/atafb.c linux-2.1.64/drivers/video/atafb.c
--- linux-2.1.64.orig/drivers/video/atafb.c	Wed Nov 19 22:34:49 1997
+++ linux-2.1.64/drivers/video/atafb.c	Fri Nov 28 12:17:26 1997
@@ -92,7 +92,6 @@
 static int sttt_xres=640,st_yres=400,tt_yres=480;
 static int sttt_xres_virtual=640,sttt_yres_virtual=400;
 static int ovsc_offset=0, ovsc_addlen=0;
-int        ovsc_switchmode=0;
 
 static struct atari_fb_par {
 	unsigned long screen_base;
@@ -2075,12 +2074,12 @@
 #define SYNC_DELAY  (mono_moni ? 1500 : 2000)
 
 /* SWITCH_ACIA may be used for Falcon (ScreenBlaster III internal!) */
-static void st_ovsc_switch(int switchmode)
+static void st_ovsc_switch(void)
 {
     unsigned long flags;
     register unsigned char old, new;
 
-    if ((switchmode & (SWITCH_ACIA | SWITCH_SND6 | SWITCH_SND7)) == 0)
+    if (!(atari_switches & ATARI_SWITCH_OVSC_MASK))
 	return;
     save_flags(flags);
     cli();
@@ -2101,11 +2100,15 @@
     mfp.tim_ct_b = 0x10;
     udelay(SYNC_DELAY);
 
-    if (switchmode == SWITCH_ACIA)
-	acia.key_ctrl = (ACIA_DIV64|ACIA_D8N1S|ACIA_RHTID|ACIA_RIE);
-    else {
+    if (atari_switches & ATARI_SWITCH_OVSC_IKBD)
+	acia.key_ctrl = ACIA_DIV64 | ACIA_D8N1S | ACIA_RHTID | ACIA_RIE;
+    if (atari_switches & ATARI_SWITCH_OVSC_MIDI)
+	acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S | ACIA_RHTID;
+    if (atari_switches & (ATARI_SWITCH_OVSC_SND6|ATARI_SWITCH_OVSC_SND7)) {
 	sound_ym.rd_data_reg_sel = 14;
-	sound_ym.wd_data = sound_ym.rd_data_reg_sel | switchmode;
+	sound_ym.wd_data = sound_ym.rd_data_reg_sel |
+			   ((atari_switches&ATARI_SWITCH_OVSC_SND6) ? 0x40:0) |
+			   ((atari_switches&ATARI_SWITCH_OVSC_SND7) ? 0x80:0);
     }
     restore_flags(flags);
 }
@@ -2794,7 +2797,7 @@
 		screen_base+=pad;
 		real_screen_base=screen_base+ovsc_offset;
 		screen_len = (mem_req - pad - ovsc_offset) & PAGE_MASK;
-		st_ovsc_switch(ovsc_switchmode);
+		st_ovsc_switch();
 		if (CPU_IS_040_OR_060) {
 			/* On a '040+, the cache mode of video RAM must be set to
 			 * write-through also for internal video hardware! */
@@ -2912,15 +2915,6 @@
 		if (hwscroll > 200)
 			hwscroll = 200;
 	}
-	else if (! strncmp(this_opt, "sw_",3)) {
-		if (! strcmp(this_opt+3, "acia"))
-			ovsc_switchmode = SWITCH_ACIA;
-		else if (! strcmp(this_opt+3, "snd6"))
-			ovsc_switchmode = SWITCH_SND6;
-		else if (! strcmp(this_opt+3, "snd7"))
-			ovsc_switchmode = SWITCH_SND7;
-		else ovsc_switchmode = SWITCH_NONE;
-	}
 #ifdef ATAFB_EXT
 	else if (!strcmp(this_opt,"mv300")) {
 		external_bitspercol = 8;
@@ -2986,7 +2980,7 @@
 		use_hwscroll=0;
     }
     else 
-      int_invalid:	ovsc_switchmode = SWITCH_NONE;
+      int_invalid:
 
 #ifdef ATAFB_EXT
     if (*ext_str) {
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.64.orig/include/asm-m68k/atarihw.h linux-2.1.64/include/asm-m68k/atarihw.h
--- linux-2.1.64.orig/include/asm-m68k/atarihw.h	Sat Nov 22 00:06:48 1997
+++ linux-2.1.64/include/asm-m68k/atarihw.h	Fri Nov 28 14:28:45 1997
@@ -25,6 +25,7 @@
 
 extern u_long atari_mch_cookie;
 extern u_long atari_mch_type;
+extern u_long atari_switches;
 extern int atari_rtc_year_offset;
 
 /* convenience macros for testing machine type */
@@ -39,6 +40,18 @@
 #define MACH_IS_HADES	(atari_mch_type == ATARI_MACH_HADES)
 #define MACH_IS_AB40	(atari_mch_type == ATARI_MACH_AB40)
 
+/* values for atari_switches */
+#define ATARI_SWITCH_IKBD	0x01
+#define ATARI_SWITCH_MIDI	0x02
+#define ATARI_SWITCH_SND6	0x04
+#define ATARI_SWITCH_SND7	0x08
+#define ATARI_SWITCH_OVSC_SHIFT	16
+#define ATARI_SWITCH_OVSC_IKBD	(ATARI_SWITCH_IKBD << ATARI_SWITCH_OVSC_SHIFT)
+#define ATARI_SWITCH_OVSC_MIDI	(ATARI_SWITCH_MIDI << ATARI_SWITCH_OVSC_SHIFT)
+#define ATARI_SWITCH_OVSC_SND6	(ATARI_SWITCH_SND6 << ATARI_SWITCH_OVSC_SHIFT)
+#define ATARI_SWITCH_OVSC_SND7	(ATARI_SWITCH_SND7 << ATARI_SWITCH_OVSC_SHIFT)
+#define ATARI_SWITCH_OVSC_MASK	0xffff0000
+	
 /*
  * Define several Hardware-Chips for indication so that for the ATARI we do
  * no longer decide whether it is a Falcon or other machine . It's just
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.64.orig/include/asm-m68k/bugs.h linux-2.1.64/include/asm-m68k/bugs.h
--- linux-2.1.64.orig/include/asm-m68k/bugs.h	Fri Nov 21 23:31:50 1997
+++ linux-2.1.64/include/asm-m68k/bugs.h	Thu Nov 27 17:11:25 1997
@@ -11,6 +11,4 @@
  *	void check_bugs(void);
  */
 
-static void check_bugs(void)
-{
-}
+extern void check_bugs(void);	/* in arch/m68k/kernel/setup.c */
