Date: Thu, 18 Dec 1997 15:29:06 GMT
From: Roman Hodek <rnhodek@faui22c.informatik.uni-erlangen.de>
To: linux-m68k@lists.linux-m68k.org
Subject: L68K: Heartbeat cleanup
Sender: owner-linux-m68k@phil.uni-sb.de


Ok, here is the promised heartbeat cleanup patch. There's now a
function pointer mach_heartbeat, as Geert proposed. I also needed a
var mach_heartbeat_irq, which tells kernel/time.c which interrupt
counter to watch.

And while a was at it, I decided that atari/config.c has grown too big
now... :-) So I spinned off some parts: all time-related stuff
(scheduler_init, hwclk stuff) has been moved to atari/time.c, and all
the debugging/serial console functions to atari/debug.c. This also
enabled me to clean up all the headers that atari/config.c includes,
they were a bit much...

I didn't dare doing the same for Amiga... :-), but there also isn't as
much clutter as was in atari/config.c.

Roman

------------------------------------------------------------------------------
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.72.orig/arch/m68k/amiga/config.c linux-2.1.72/arch/m68k/amiga/config.c
--- linux-2.1.72.orig/arch/m68k/amiga/config.c	Thu Dec 18 11:19:38 1997
+++ linux-2.1.72/arch/m68k/amiga/config.c	Thu Dec 18 14:20:45 1997
@@ -85,6 +85,7 @@
 void amiga_serial_console_write(struct console *co, const char *s,
 				unsigned int count);
 static void amiga_debug_init(void);
+static void amiga_heartbeat(int on);
 
 static struct console amiga_console_driver = {
 	"debug",
@@ -381,6 +382,10 @@
   mach_sysrq_shift_mask = 0xff;  /* all modifiers except CapsLock */
   mach_sysrq_xlate = amiga_sysrq_xlate;
 #endif
+#ifdef CONFIG_HEARTBEAT
+  mach_heartbeat = amiga_heartbeat;
+  mach_heartbeat_irq = SYS_IRQS + IRQ_AMIGA_CIAB_TA;
+#endif
 
   /* Fill in the clock values (based on the 700 kHz E-Clock) */
   amiga_masterclock = 40*amiga_eclock;	/* 28 MHz */
@@ -888,6 +893,15 @@
 	}
 }
 
+#ifdef CONFIG_HEARTBEAT
+static void amiga_heartbeat(int on)
+{
+    if (on)
+	ciaa.pra &= ~2;
+    else
+	ciaa.pra |= 2;
+}
+#endif
 
     /*
      *  Amiga specific parts of /proc
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.72.orig/arch/m68k/atari/Makefile linux-2.1.72/arch/m68k/atari/Makefile
--- linux-2.1.72.orig/arch/m68k/atari/Makefile	Sun Sep 14 22:47:02 1997
+++ linux-2.1.72/arch/m68k/atari/Makefile	Thu Dec 18 14:03:21 1997
@@ -8,7 +8,8 @@
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
 O_TARGET := atari.o
-O_OBJS	 := config.o atakeyb.o ataints.o stdma.o atasound.o joystick.o stram.o
+O_OBJS	 := config.o time.o debug.o atakeyb.o ataints.o stdma.o atasound.o \
+            joystick.o stram.o
 OX_OBJS  := atari_ksyms.o
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.72.orig/arch/m68k/atari/config.c linux-2.1.72/arch/m68k/atari/config.c
--- linux-2.1.72.orig/arch/m68k/atari/config.c	Wed Dec 17 13:36:38 1997
+++ linux-2.1.72/arch/m68k/atari/config.c	Thu Dec 18 16:09:49 1997
@@ -27,30 +27,17 @@
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/mm.h>
-#include <linux/mc146818rtc.h>
-#include <linux/kd.h>
-#include <linux/tty.h>
 #include <linux/console.h>
-#include <linux/interrupt.h>
 #include <linux/init.h>
-#include <linux/delay.h>
 
 #include <asm/bootinfo.h>
 #include <asm/setup.h>
 #include <asm/atarihw.h>
 #include <asm/atariints.h>
 #include <asm/atari_stram.h>
-
 #include <asm/system.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/pgtable.h>
 #include <asm/machdep.h>
 
-#ifdef CONFIG_KGDB
-#include <asm/kgdb.h>
-#endif
-
 u_long atari_mch_cookie;
 u_long atari_mch_type = 0;
 struct atari_hw_present atari_hw_present;
@@ -58,9 +45,14 @@
 int atari_dont_touch_floppy_select = 0;
 int atari_rtc_year_offset;
 
-extern char m68k_debug_device[];
+/* local function prototypes */
+static void atari_reset( void );
+#ifdef CONFIG_ATARI_FLOPPY
+extern void atari_floppy_setup(char *, int *);
+#endif
+static void atari_get_model(char *model);
+static int atari_get_hardware_list(char *buffer);
 
-static void atari_sched_init(void (*)(int, void *, struct pt_regs *));
 /* atari specific keyboard functions */
 extern int atari_keyb_init(void);
 extern int atari_kbdrate (struct kbd_repeat *);
@@ -73,45 +65,24 @@
 extern void atari_enable_irq (unsigned int);
 extern void atari_disable_irq (unsigned int);
 extern int atari_get_irq_list (char *buf);
-static void atari_get_model(char *model);
-static int atari_get_hardware_list(char *buffer);
-/* atari specific timer functions */
-static unsigned long atari_gettimeoffset (void);
-static void atari_mste_gettod (int *, int *, int *, int *, int *, int *);
-static void atari_gettod (int *, int *, int *, int *, int *, int *);
-static int atari_mste_hwclk (int, struct hwclk_time *);
-static int atari_hwclk (int, struct hwclk_time *);
-static int atari_mste_set_clock_mmss (unsigned long);
-static int atari_set_clock_mmss (unsigned long);
 extern void atari_mksound( unsigned int count, unsigned int ticks );
-static void atari_reset( void );
-#ifdef CONFIG_ATARI_FLOPPY
-extern void atari_floppy_setup(char *, int *);
+#ifdef CONFIG_HEARTBEAT
+static void atari_heartbeat( int on );
 #endif
 extern struct consw fb_con;
-static void atari_debug_init(void);
 
-static struct console atari_console_driver = {
-	"debug",
-	NULL,			/* write */
-	NULL,			/* read */
-	NULL,			/* device */
-	NULL,			/* wait_key */
-	NULL,			/* unblank */
-	NULL,			/* setup */
-	CON_PRINTBUFFER,
-	-1,
-	0,
-	NULL
-};
-
-/* Flag that Modem1 port is already initialized and used */
-int atari_MFP_init_done = 0;
-/* Flag that Modem1 port is already initialized and used */
-int atari_SCC_init_done = 0;
-/* Can be set somewhere, if a SCC master reset has already be done and should
- * not be repeated; used by kgdb */
-int atari_SCC_reset_done = 0;
+/* atari specific timer functions (in time.c) */
+extern void atari_sched_init(void (*)(int, void *, struct pt_regs *));
+extern unsigned long atari_gettimeoffset (void);
+extern void atari_mste_gettod (int *, int *, int *, int *, int *, int *);
+extern void atari_tt_gettod (int *, int *, int *, int *, int *, int *);
+extern int atari_mste_hwclk (int, struct hwclk_time *);
+extern int atari_tt_hwclk (int, struct hwclk_time *);
+extern int atari_mste_set_clock_mmss (unsigned long);
+extern int atari_tt_set_clock_mmss (unsigned long);
+
+/* atari specific debug functions (in debug.c) */
+extern void atari_debug_init(void);
 
 #ifdef CONFIG_MAGIC_SYSRQ
 static char atari_sysrq_xlate[128] =
@@ -352,6 +323,10 @@
     mach_sysrq_shift_mask = 0xff; /* all modifiers except CapsLock */
     mach_sysrq_xlate = atari_sysrq_xlate;
 #endif
+#ifdef CONFIG_HEARTBEAT
+    mach_heartbeat = atari_heartbeat;
+    mach_heartbeat_irq = IRQ_MFP_TIMC;
+#endif
 
     /* Set switches as requested by the user */
     if (atari_switches & ATARI_SWITCH_IKBD)
@@ -505,9 +480,9 @@
     if (hwreg_present( &tt_rtc.regsel )) {
 	ATARIHW_SET(TT_CLK);
         printk( "TT_CLK " );
-        mach_gettod = atari_gettod;
-        mach_hwclk = atari_hwclk;
-        mach_set_clock_mmss = atari_set_clock_mmss;
+        mach_gettod = atari_tt_gettod;
+        mach_hwclk = atari_tt_hwclk;
+        mach_set_clock_mmss = atari_tt_set_clock_mmss;
     }
     if (!MACH_IS_HADES && hwreg_present( &mste_rtc.sec_ones)) {
 	ATARIHW_SET(MSTE_CLK);
@@ -612,704 +587,23 @@
     atari_rtc_year_offset = (tos_version < 0x306) ? 70 : 68;
 }
 
-__initfunc(static void
-atari_sched_init(void (*timer_routine)(int, void *, struct pt_regs *)))
-{
-    /* set Timer C data Register */
-    mfp.tim_dt_c = INT_TICKS;
-    /* start timer C, div = 1:100 */
-    mfp.tim_ct_cd = (mfp.tim_ct_cd & 15) | 0x60; 
-    /* install interrupt service routine for MFP Timer C */
-    request_irq(IRQ_MFP_TIMC, timer_routine, IRQ_TYPE_SLOW,
-                "timer", timer_routine);
-}
-
-/* ++andreas: gettimeoffset fixed to check for pending interrupt */
-
-#define TICK_SIZE 10000
-  
-/* This is always executed with interrupts disabled.  */
-static unsigned long atari_gettimeoffset (void)
-{
-  unsigned long ticks, offset = 0;
-
-  /* read MFP timer C current value */
-  ticks = mfp.tim_dt_c;
-  /* The probability of underflow is less than 2% */
-  if (ticks > INT_TICKS - INT_TICKS / 50)
-    /* Check for pending timer interrupt */
-    if (mfp.int_pn_b & (1 << 5))
-      offset = TICK_SIZE;
-
-  ticks = INT_TICKS - ticks;
-  ticks = ticks * 10000L / INT_TICKS;
-
-  return ticks + offset;
-}
-
-
-static void
-mste_read(struct MSTE_RTC *val)
-{
-#define COPY(v) val->v=(mste_rtc.v & 0xf)
-	do {
-		COPY(sec_ones) ; COPY(sec_tens) ; COPY(min_ones) ; 
-		COPY(min_tens) ; COPY(hr_ones) ; COPY(hr_tens) ; 
-		COPY(weekday) ; COPY(day_ones) ; COPY(day_tens) ; 
-		COPY(mon_ones) ; COPY(mon_tens) ; COPY(year_ones) ;
-		COPY(year_tens) ;
-	/* prevent from reading the clock while it changed */
-	} while (val->sec_ones != (mste_rtc.sec_ones & 0xf));
-#undef COPY
-}
-
-static void
-mste_write(struct MSTE_RTC *val)
-{
-#define COPY(v) mste_rtc.v=val->v
-	do {
-		COPY(sec_ones) ; COPY(sec_tens) ; COPY(min_ones) ; 
-		COPY(min_tens) ; COPY(hr_ones) ; COPY(hr_tens) ; 
-		COPY(weekday) ; COPY(day_ones) ; COPY(day_tens) ; 
-		COPY(mon_ones) ; COPY(mon_tens) ; COPY(year_ones) ;
-		COPY(year_tens) ;
-	/* prevent from writing the clock while it changed */
-	} while (val->sec_ones != (mste_rtc.sec_ones & 0xf));
-#undef COPY
-}
-
-#define	RTC_READ(reg)				\
-    ({	unsigned char	__val;			\
-		outb(reg,&tt_rtc.regsel);	\
-		__val = tt_rtc.data;		\
-		__val;				\
-	})
-
-#define	RTC_WRITE(reg,val)			\
-    do {					\
-		outb(reg,&tt_rtc.regsel);	\
-		tt_rtc.data = (val);		\
-	} while(0)
-
-
-static void atari_mste_gettod (int *yearp, int *monp, int *dayp,
-			       int *hourp, int *minp, int *secp)
-{
-    int hr24=0, hour;
-    struct MSTE_RTC val;
-
-    mste_rtc.mode=(mste_rtc.mode | 1);
-    hr24=mste_rtc.mon_tens & 1;
-    mste_rtc.mode=(mste_rtc.mode & ~1);
-
-    mste_read(&val);
-    *secp = val.sec_ones + val.sec_tens * 10;
-    *minp = val.min_ones + val.min_tens * 10;
-    hour = val.hr_ones + val.hr_tens * 10;
-    if (!hr24) {
-        if (hour == 12 || hour == 12 + 20)
-	    hour -= 12;
-	if (hour >= 20)
-	    hour += 12 - 20;
-    }
-    *hourp = hour;
-    *dayp = val.day_ones + val.day_tens * 10;
-    *monp = val.mon_ones + val.mon_tens * 10;
-    *yearp = val.year_ones + val.year_tens * 10 + 80;	
-}
-
-  
-static void atari_gettod (int *yearp, int *monp, int *dayp,
-			  int *hourp, int *minp, int *secp)
-{
-    unsigned char	ctrl;
-    int hour, pm;
-
-    while (!(RTC_READ(RTC_FREQ_SELECT) & RTC_UIP)) ;
-    while (RTC_READ(RTC_FREQ_SELECT) & RTC_UIP) ;
-
-    *secp  = RTC_READ(RTC_SECONDS);
-    *minp  = RTC_READ(RTC_MINUTES);
-    hour = RTC_READ(RTC_HOURS);
-    *dayp  = RTC_READ(RTC_DAY_OF_MONTH);
-    *monp  = RTC_READ(RTC_MONTH);
-    *yearp = RTC_READ(RTC_YEAR);
-    pm = hour & 0x80;
-    hour &= ~0x80;
-
-    ctrl = RTC_READ(RTC_CONTROL); 
-
-    if (!(ctrl & RTC_DM_BINARY)) {
-        BCD_TO_BIN(*secp);
-        BCD_TO_BIN(*minp);
-        BCD_TO_BIN(hour);
-        BCD_TO_BIN(*dayp);
-        BCD_TO_BIN(*monp);
-        BCD_TO_BIN(*yearp);
-    }
-    if (!(ctrl & RTC_24H)) {
-	if (!pm && hour == 12)
-	    hour = 0;
-	else if (pm && hour != 12)
-            hour += 12;
-    }
-    *hourp = hour;
-
-    /* Adjust values (let the setup valid) */
-    *yearp += atari_rtc_year_offset;
-}
-
-#define HWCLK_POLL_INTERVAL	5
-
-static int atari_mste_hwclk( int op, struct hwclk_time *t )
+#ifdef CONFIG_HEARTBEAT
+static void atari_heartbeat( int on )
 {
-    int hour, year;
-    int hr24=0;
-    struct MSTE_RTC val;
-    
-    mste_rtc.mode=(mste_rtc.mode | 1);
-    hr24=mste_rtc.mon_tens & 1;
-    mste_rtc.mode=(mste_rtc.mode & ~1);
-
-    if (op) {
-        /* write: prepare values */
-        
-        val.sec_ones = t->sec % 10;
-        val.sec_tens = t->sec / 10;
-        val.min_ones = t->min % 10;
-        val.min_tens = t->min / 10;
-        hour = t->hour;
-        if (!hr24) {
-	    if (hour > 11)
-		hour += 20 - 12;
-	    if (hour == 0 || hour == 20)
-		hour += 12;
-        }
-        val.hr_ones = hour % 10;
-        val.hr_tens = hour / 10;
-        val.day_ones = t->day % 10;
-        val.day_tens = t->day / 10;
-        val.mon_ones = (t->mon+1) % 10;
-        val.mon_tens = (t->mon+1) / 10;
-        year = t->year - 80;
-        val.year_ones = year % 10;
-        val.year_tens = year / 10;
-        val.weekday = t->wday;
-        mste_write(&val);
-        mste_rtc.mode=(mste_rtc.mode | 1);
-        val.year_ones = (year % 4);	/* leap year register */
-        mste_rtc.mode=(mste_rtc.mode & ~1);
-    }
-    else {
-        mste_read(&val);
-        t->sec = val.sec_ones + val.sec_tens * 10;
-        t->min = val.min_ones + val.min_tens * 10;
-        hour = val.hr_ones + val.hr_tens * 10;
-	if (!hr24) {
-	    if (hour == 12 || hour == 12 + 20)
-		hour -= 12;
-	    if (hour >= 20)
-                hour += 12 - 20;
-        }
-	t->hour = hour;
-	t->day = val.day_ones + val.day_tens * 10;
-        t->mon = val.mon_ones + val.mon_tens * 10 - 1;
-        t->year = val.year_ones + val.year_tens * 10 + 80;
-        t->wday = val.weekday;
-    }
-    return 0;
-}
+    unsigned char tmp;
+    unsigned long flags;
 
-static int atari_hwclk( int op, struct hwclk_time *t )
-{
-    int sec=0, min=0, hour=0, day=0, mon=0, year=0, wday=0; 
-    unsigned long 	flags;
-    unsigned char	ctrl;
-    int pm = 0;
-
-    ctrl = RTC_READ(RTC_CONTROL); /* control registers are
-                                   * independent from the UIP */
-
-    if (op) {
-        /* write: prepare values */
-        
-        sec  = t->sec;
-        min  = t->min;
-        hour = t->hour;
-        day  = t->day;
-        mon  = t->mon + 1;
-        year = t->year - atari_rtc_year_offset;
-        wday = t->wday + (t->wday >= 0);
-        
-        if (!(ctrl & RTC_24H)) {
-	    if (hour > 11) {
-		pm = 0x80;
-		if (hour != 12)
-		    hour -= 12;
-	    }
-	    else if (hour == 0)
-		hour = 12;
-        }
-        
-        if (!(ctrl & RTC_DM_BINARY)) {
-            BIN_TO_BCD(sec);
-            BIN_TO_BCD(min);
-            BIN_TO_BCD(hour);
-            BIN_TO_BCD(day);
-            BIN_TO_BCD(mon);
-            BIN_TO_BCD(year);
-            if (wday >= 0) BIN_TO_BCD(wday);
-        }
-    }
+    if (atari_dont_touch_floppy_select)
+	return;
     
-    /* Reading/writing the clock registers is a bit critical due to
-     * the regular update cycle of the RTC. While an update is in
-     * progress, registers 0..9 shouldn't be touched.
-     * The problem is solved like that: If an update is currently in
-     * progress (the UIP bit is set), the process sleeps for a while
-     * (50ms). This really should be enough, since the update cycle
-     * normally needs 2 ms.
-     * If the UIP bit reads as 0, we have at least 244 usecs until the
-     * update starts. This should be enough... But to be sure,
-     * additionally the RTC_SET bit is set to prevent an update cycle.
-     */
-
-    while( RTC_READ(RTC_FREQ_SELECT) & RTC_UIP ) {
-        current->state = TASK_INTERRUPTIBLE;
-        current->timeout = jiffies + HWCLK_POLL_INTERVAL;
-        schedule();
-    }
-
     save_flags(flags);
     cli();
-    RTC_WRITE( RTC_CONTROL, ctrl | RTC_SET );
-    if (!op) {
-        sec  = RTC_READ( RTC_SECONDS );
-        min  = RTC_READ( RTC_MINUTES );
-        hour = RTC_READ( RTC_HOURS );
-        day  = RTC_READ( RTC_DAY_OF_MONTH );
-        mon  = RTC_READ( RTC_MONTH );
-        year = RTC_READ( RTC_YEAR );
-        wday = RTC_READ( RTC_DAY_OF_WEEK );
-    }
-    else {
-        RTC_WRITE( RTC_SECONDS, sec );
-        RTC_WRITE( RTC_MINUTES, min );
-        RTC_WRITE( RTC_HOURS, hour + pm);
-        RTC_WRITE( RTC_DAY_OF_MONTH, day );
-        RTC_WRITE( RTC_MONTH, mon );
-        RTC_WRITE( RTC_YEAR, year );
-        if (wday >= 0) RTC_WRITE( RTC_DAY_OF_WEEK, wday );
-    }
-    RTC_WRITE( RTC_CONTROL, ctrl & ~RTC_SET );
-    restore_flags(flags);
-
-    if (!op) {
-        /* read: adjust values */
-        
-        if (hour & 0x80) {
-	    hour &= ~0x80;
-	    pm = 1;
-	}
-
-	if (!(ctrl & RTC_DM_BINARY)) {
-            BCD_TO_BIN(sec);
-            BCD_TO_BIN(min);
-            BCD_TO_BIN(hour);
-            BCD_TO_BIN(day);
-            BCD_TO_BIN(mon);
-            BCD_TO_BIN(year);
-            BCD_TO_BIN(wday);
-        }
-
-        if (!(ctrl & RTC_24H)) {
-	    if (!pm && hour == 12)
-		hour = 0;
-	    else if (pm && hour != 12)
-		hour += 12;
-        }
-
-        t->sec  = sec;
-        t->min  = min;
-        t->hour = hour;
-        t->day  = day;
-        t->mon  = mon - 1;
-        t->year = year + atari_rtc_year_offset;
-        t->wday = wday - 1;
-    }
-
-    return( 0 );
-}
-
-
-static int atari_mste_set_clock_mmss (unsigned long nowtime)
-{
-    short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
-    struct MSTE_RTC val;
-    unsigned char rtc_minutes;
-
-    mste_read(&val);  
-    rtc_minutes= val.min_ones + val.min_tens * 10;
-    if ((rtc_minutes < real_minutes
-         ? real_minutes - rtc_minutes
-         : rtc_minutes - real_minutes) < 30)
-    {
-        val.sec_ones = real_seconds % 10;
-        val.sec_tens = real_seconds / 10;
-        val.min_ones = real_minutes % 10;
-        val.min_tens = real_minutes / 10;
-        mste_write(&val);
-    }
-    else
-        return -1;
-    return 0;
-}
-
-static int atari_set_clock_mmss (unsigned long nowtime)
-{
-    int retval = 0;
-    short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
-    unsigned char save_control, save_freq_select, rtc_minutes;
-
-    save_control = RTC_READ (RTC_CONTROL); /* tell the clock it's being set */
-    RTC_WRITE (RTC_CONTROL, save_control | RTC_SET);
-
-    save_freq_select = RTC_READ (RTC_FREQ_SELECT); /* stop and reset prescaler */
-    RTC_WRITE (RTC_FREQ_SELECT, save_freq_select | RTC_DIV_RESET2);
-
-    rtc_minutes = RTC_READ (RTC_MINUTES);
-    if (!(save_control & RTC_DM_BINARY))
-        BCD_TO_BIN (rtc_minutes);
-
-    /* Since we're only adjusting minutes and seconds, don't interfere
-       with hour overflow.  This avoids messing with unknown time zones
-       but requires your RTC not to be off by more than 30 minutes.  */
-    if ((rtc_minutes < real_minutes
-         ? real_minutes - rtc_minutes
-         : rtc_minutes - real_minutes) < 30)
-        {
-            if (!(save_control & RTC_DM_BINARY))
-                {
-                    BIN_TO_BCD (real_seconds);
-                    BIN_TO_BCD (real_minutes);
-                }
-            RTC_WRITE (RTC_SECONDS, real_seconds);
-            RTC_WRITE (RTC_MINUTES, real_minutes);
-        }
-    else
-        retval = -1;
-
-    RTC_WRITE (RTC_FREQ_SELECT, save_freq_select);
-    RTC_WRITE (RTC_CONTROL, save_control);
-    return retval;
-}
-
-
-static inline void ata_mfp_out (char c)
-{
-    while (!(mfp.trn_stat & 0x80)) /* wait for tx buf empty */
-	barrier ();
-    mfp.usart_dta = c;
-}
-
-void atari_mfp_console_write (struct console *co, const char *str,
-			      unsigned int count)
-{
-    while (count--) {
-	if (*str == '\n')
-	    ata_mfp_out( '\r' );
-	ata_mfp_out( *str++ );
-    }
-}
-
-static inline void ata_scc_out (char c)
-{
-    do {
-	MFPDELAY();
-    } while (!(scc.cha_b_ctrl & 0x04)); /* wait for tx buf empty */
-    MFPDELAY();
-    scc.cha_b_data = c;
-}
-
-void atari_scc_console_write (struct console *co, const char *str,
-			      unsigned int count)
-{
-    while (count--) {
-	if (*str == '\n')
-	    ata_scc_out( '\r' );
-	ata_scc_out( *str++ );
-    }
-}
-
-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 (struct console *co, 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;
-    /* This a some-seconds timeout in case no printer is connected */
-    unsigned long i = loops_per_sec > 1 ? loops_per_sec : 10000000;
-
-    while( (mfp.par_dt_reg & 1) && --i ) /* wait for BUSY == L */
-	;
-    if (!i) return( 0 );
-    
-    sound_ym.rd_data_reg_sel = 15;  /* select port B */
-    sound_ym.wd_data = c;           /* put char onto port */
-    sound_ym.rd_data_reg_sel = 14;  /* select port A */
+    sound_ym.rd_data_reg_sel = 14; /* Select PSG Port A */
     tmp = sound_ym.rd_data_reg_sel;
-    sound_ym.wd_data = tmp & ~0x20; /* set strobe L */
-    MFPDELAY();                     /* wait a bit */
-    sound_ym.wd_data = tmp | 0x20;  /* set strobe H */
-    return( 1 );
-}
-
-static void atari_par_console_write (struct console *co, const char *str,
-				     unsigned int count)
-{
-    static int printer_present = 1;
-
-    if (!printer_present)
-	return;
-
-    while (count--) {
-	if (*str == '\n')
-	    if (!ata_par_out( '\r' )) {
-		printer_present = 0;
-		return;
-	    }
-	if (!ata_par_out( *str++ )) {
-	    printer_present = 0;
-	    return;
-	}
-    }
-}
-
-#ifdef CONFIG_SERIAL_CONSOLE
-int atari_mfp_console_wait_key(struct console *co)
-{
-    while( !(mfp.rcv_stat & 0x80) ) /* wait for rx buf filled */
-	barrier();
-    return( mfp.usart_dta );
-}
-
-int atari_scc_console_wait_key(struct console *co)
-{
-    do {
-	MFPDELAY();
-    } while( !(scc.cha_b_ctrl & 0x01) ); /* wait for rx buf filled */
-    MFPDELAY();
-    return( scc.cha_b_data );
-}
-
-int atari_midi_console_wait_key(struct console *co)
-{
-    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
- * SCC serial ports. They're used by the debugging interface, kgdb, and the
- * serial console code. */
-#ifndef CONFIG_SERIAL_CONSOLE
-__initfunc(static void atari_init_mfp_port( int cflag ))
-#else
-void atari_init_mfp_port( int cflag )
-#endif
-{
-    /* timer values for 1200...115200 bps; > 38400 select 110, 134, or 150
-     * bps, resp., and work only correct if there's a RSVE or RSSPEED */
-    static int baud_table[9] = { 16, 11, 8, 4, 2, 1, 175, 143, 128 };
-    int baud = cflag & CBAUD;
-    int parity = (cflag & PARENB) ? ((cflag & PARODD) ? 0x04 : 0x06) : 0;
-    int csize = ((cflag & CSIZE) == CS7) ? 0x20 : 0x00;
-
-    if (cflag & CBAUDEX)
-	baud += B38400;
-    if (baud < B1200 || baud > B38400+2)
-	baud = B9600; /* use default 9600bps for non-implemented rates */
-    baud -= B1200; /* baud_table[] starts at 1200bps */
-	
-    mfp.trn_stat &= ~0x01; /* disable TX */
-    mfp.usart_ctr = parity | csize | 0x88; /* 1:16 clk mode, 1 stop bit */
-    mfp.tim_ct_cd &= 0x70;  /* stop timer D */
-    mfp.tim_dt_d = baud_table[baud];
-    mfp.tim_ct_cd |= 0x01;  /* start timer D, 1:4 */
-    mfp.trn_stat |= 0x01;  /* enable TX */
-
-    atari_MFP_init_done = 1;
-}
-
-#define SCC_WRITE(reg,val)				\
-    do {						\
-	scc.cha_b_ctrl = (reg);				\
-	MFPDELAY();					\
-	scc.cha_b_ctrl = (val);				\
-	MFPDELAY();					\
-    } while(0)
-
-/* loops_per_sec isn't initialized yet, so we can't use udelay(). This does a
- * delay of ~ 60us. */
-#define LONG_DELAY()				\
-    do {					\
-	int i;					\
-	for( i = 100; i > 0; --i )		\
-	    MFPDELAY();				\
-    } while(0)
-    
-#ifndef CONFIG_SERIAL_CONSOLE
-__initfunc(static void atari_init_scc_port( int cflag ))
-#else
-void atari_init_scc_port( int cflag )
-#endif
-{
-    extern int atari_SCC_reset_done;
-    static int clksrc_table[9] =
-	/* reg 11: 0x50 = BRG, 0x00 = RTxC, 0x28 = TRxC */
-    	{ 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00 };
-    static int brgsrc_table[9] =
-	/* reg 14: 0 = RTxC, 2 = PCLK */
-    	{ 2, 2, 2, 2, 2, 2, 0, 2, 2 };
-    static int clkmode_table[9] =
-	/* reg 4: 0x40 = x16, 0x80 = x32, 0xc0 = x64 */
-    	{ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x80 };
-    static int div_table[9] =
-	/* reg12 (BRG low) */
-    	{ 208, 138, 103, 50, 24, 11, 1, 0, 0 };
-
-    int baud = cflag & CBAUD;
-    int clksrc, clkmode, div, reg3, reg5;
-    
-    if (cflag & CBAUDEX)
-	baud += B38400;
-    if (baud < B1200 || baud > B38400+2)
-	baud = B9600; /* use default 9600bps for non-implemented rates */
-    baud -= B1200; /* tables starts at 1200bps */
-
-    clksrc  = clksrc_table[baud];
-    clkmode = clkmode_table[baud];
-    div     = div_table[baud];
-    if (ATARIHW_PRESENT(TT_MFP) && baud >= 6) {
-	/* special treatment for TT, where rates >= 38400 are done via TRxC */
-	clksrc = 0x28; /* TRxC */
-	clkmode = baud == 6 ? 0xc0 :
-		  baud == 7 ? 0x80 : /* really 76800bps */
-			      0x40;  /* really 153600bps */
-	div = 0;
-    }
-
-    reg3 = (cflag & CSIZE) == CS8 ? 0xc0 : 0x40;
-    reg5 = (cflag & CSIZE) == CS8 ? 0x60 : 0x20 | 0x82 /* assert DTR/RTS */;
-    
-    (void)scc.cha_b_ctrl;	/* reset reg pointer */
-    SCC_WRITE( 9, 0xc0 );	/* reset */
-    LONG_DELAY();		/* extra delay after WR9 access */
-    SCC_WRITE( 4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03) : 0 |
-		  0x04 /* 1 stopbit */ |
-		  clkmode );
-    SCC_WRITE( 3, reg3 );
-    SCC_WRITE( 5, reg5 );
-    SCC_WRITE( 9, 0 );		/* no interrupts */
-    LONG_DELAY();		/* extra delay after WR9 access */
-    SCC_WRITE( 10, 0 );		/* NRZ mode */
-    SCC_WRITE( 11, clksrc );	/* main clock source */
-    SCC_WRITE( 12, div );	/* BRG value */
-    SCC_WRITE( 13, 0 );		/* BRG high byte */
-    SCC_WRITE( 14, brgsrc_table[baud] );
-    SCC_WRITE( 14, brgsrc_table[baud] | (div ? 1 : 0) );
-    SCC_WRITE( 3, reg3 | 1 );
-    SCC_WRITE( 5, reg5 | 8 );
-    
-    atari_SCC_reset_done = 1;
-    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);
+    sound_ym.wd_data = on ? (tmp & ~0x02) : (tmp | 0x02);
+    restore_flags(flags);
 }
-
-__initfunc(static void atari_debug_init(void))
-{
-#ifdef CONFIG_KGDB
-    /* the m68k_debug_device is used by the GDB stub, do nothing here */
-    return;
 #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" );
-
-    }
-
-    if (!strcmp( m68k_debug_device, "ser1" )) {
-	/* ST-MFP Modem1 serial port */
-	atari_init_mfp_port( B9600|CS8 );
-	atari_console_driver.write = atari_mfp_console_write;
-    }
-    else if (!strcmp( m68k_debug_device, "ser2" )) {
-	/* SCC Modem2 serial port */
-	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 */
-	sound_ym.rd_data_reg_sel = 7;  /* select mixer control */
-	sound_ym.wd_data = 0xff;       /* sound off, ports are output */
-	sound_ym.rd_data_reg_sel = 15; /* select port B */
-	sound_ym.wd_data = 0;          /* no char */
-	sound_ym.rd_data_reg_sel = 14; /* select port A */
-	sound_ym.wd_data = sound_ym.rd_data_reg_sel | 0x20; /* strobe H */
-	atari_console_driver.write = atari_par_console_write;
-    }
-    if (atari_console_driver.write)
-	register_console(&atari_console_driver);
-}
 
 /* ++roman:
  *
@@ -1512,3 +806,10 @@
 
     return(len);
 }
+
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  tab-width: 8
+ * End:
+ */
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.72.orig/arch/m68k/atari/debug.c linux-2.1.72/arch/m68k/atari/debug.c
--- linux-2.1.72.orig/arch/m68k/atari/debug.c	Thu Jan  1 01:00:00 1970
+++ linux-2.1.72/arch/m68k/atari/debug.c	Thu Dec 18 16:05:32 1997
@@ -0,0 +1,359 @@
+/*
+ * linux/arch/m68k/atari/debug.c
+ *
+ * Atari debugging and serial console stuff
+ *
+ * Assembled of parts of former atari/config.c 97-12-18 by Roman Hodek
+ *  
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include <asm/atarihw.h>
+#include <asm/atariints.h>
+
+extern char m68k_debug_device[];
+
+/* Flag that Modem1 port is already initialized and used */
+int atari_MFP_init_done = 0;
+/* Flag that Modem1 port is already initialized and used */
+int atari_SCC_init_done = 0;
+/* Can be set somewhere, if a SCC master reset has already be done and should
+ * not be repeated; used by kgdb */
+int atari_SCC_reset_done = 0;
+
+static struct console atari_console_driver = {
+	"debug",
+	NULL,			/* write */
+	NULL,			/* read */
+	NULL,			/* device */
+	NULL,			/* wait_key */
+	NULL,			/* unblank */
+	NULL,			/* setup */
+	CON_PRINTBUFFER,
+	-1,
+	0,
+	NULL
+};
+
+
+static inline void ata_mfp_out (char c)
+{
+    while (!(mfp.trn_stat & 0x80)) /* wait for tx buf empty */
+	barrier ();
+    mfp.usart_dta = c;
+}
+
+void atari_mfp_console_write (struct console *co, const char *str,
+			      unsigned int count)
+{
+    while (count--) {
+	if (*str == '\n')
+	    ata_mfp_out( '\r' );
+	ata_mfp_out( *str++ );
+    }
+}
+
+static inline void ata_scc_out (char c)
+{
+    do {
+	MFPDELAY();
+    } while (!(scc.cha_b_ctrl & 0x04)); /* wait for tx buf empty */
+    MFPDELAY();
+    scc.cha_b_data = c;
+}
+
+void atari_scc_console_write (struct console *co, const char *str,
+			      unsigned int count)
+{
+    while (count--) {
+	if (*str == '\n')
+	    ata_scc_out( '\r' );
+	ata_scc_out( *str++ );
+    }
+}
+
+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 (struct console *co, 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;
+    /* This a some-seconds timeout in case no printer is connected */
+    unsigned long i = loops_per_sec > 1 ? loops_per_sec : 10000000;
+
+    while( (mfp.par_dt_reg & 1) && --i ) /* wait for BUSY == L */
+	;
+    if (!i) return( 0 );
+    
+    sound_ym.rd_data_reg_sel = 15;  /* select port B */
+    sound_ym.wd_data = c;           /* put char onto port */
+    sound_ym.rd_data_reg_sel = 14;  /* select port A */
+    tmp = sound_ym.rd_data_reg_sel;
+    sound_ym.wd_data = tmp & ~0x20; /* set strobe L */
+    MFPDELAY();                     /* wait a bit */
+    sound_ym.wd_data = tmp | 0x20;  /* set strobe H */
+    return( 1 );
+}
+
+static void atari_par_console_write (struct console *co, const char *str,
+				     unsigned int count)
+{
+    static int printer_present = 1;
+
+    if (!printer_present)
+	return;
+
+    while (count--) {
+	if (*str == '\n')
+	    if (!ata_par_out( '\r' )) {
+		printer_present = 0;
+		return;
+	    }
+	if (!ata_par_out( *str++ )) {
+	    printer_present = 0;
+	    return;
+	}
+    }
+}
+
+#ifdef CONFIG_SERIAL_CONSOLE
+int atari_mfp_console_wait_key(struct console *co)
+{
+    while( !(mfp.rcv_stat & 0x80) ) /* wait for rx buf filled */
+	barrier();
+    return( mfp.usart_dta );
+}
+
+int atari_scc_console_wait_key(struct console *co)
+{
+    do {
+	MFPDELAY();
+    } while( !(scc.cha_b_ctrl & 0x01) ); /* wait for rx buf filled */
+    MFPDELAY();
+    return( scc.cha_b_data );
+}
+
+int atari_midi_console_wait_key(struct console *co)
+{
+    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
+ * SCC serial ports. They're used by the debugging interface, kgdb, and the
+ * serial console code. */
+#ifndef CONFIG_SERIAL_CONSOLE
+__initfunc(static void atari_init_mfp_port( int cflag ))
+#else
+void atari_init_mfp_port( int cflag )
+#endif
+{
+    /* timer values for 1200...115200 bps; > 38400 select 110, 134, or 150
+     * bps, resp., and work only correct if there's a RSVE or RSSPEED */
+    static int baud_table[9] = { 16, 11, 8, 4, 2, 1, 175, 143, 128 };
+    int baud = cflag & CBAUD;
+    int parity = (cflag & PARENB) ? ((cflag & PARODD) ? 0x04 : 0x06) : 0;
+    int csize = ((cflag & CSIZE) == CS7) ? 0x20 : 0x00;
+
+    if (cflag & CBAUDEX)
+	baud += B38400;
+    if (baud < B1200 || baud > B38400+2)
+	baud = B9600; /* use default 9600bps for non-implemented rates */
+    baud -= B1200; /* baud_table[] starts at 1200bps */
+	
+    mfp.trn_stat &= ~0x01; /* disable TX */
+    mfp.usart_ctr = parity | csize | 0x88; /* 1:16 clk mode, 1 stop bit */
+    mfp.tim_ct_cd &= 0x70;  /* stop timer D */
+    mfp.tim_dt_d = baud_table[baud];
+    mfp.tim_ct_cd |= 0x01;  /* start timer D, 1:4 */
+    mfp.trn_stat |= 0x01;  /* enable TX */
+
+    atari_MFP_init_done = 1;
+}
+
+#define SCC_WRITE(reg,val)				\
+    do {						\
+	scc.cha_b_ctrl = (reg);				\
+	MFPDELAY();					\
+	scc.cha_b_ctrl = (val);				\
+	MFPDELAY();					\
+    } while(0)
+
+/* loops_per_sec isn't initialized yet, so we can't use udelay(). This does a
+ * delay of ~ 60us. */
+#define LONG_DELAY()				\
+    do {					\
+	int i;					\
+	for( i = 100; i > 0; --i )		\
+	    MFPDELAY();				\
+    } while(0)
+    
+#ifndef CONFIG_SERIAL_CONSOLE
+__initfunc(static void atari_init_scc_port( int cflag ))
+#else
+void atari_init_scc_port( int cflag )
+#endif
+{
+    extern int atari_SCC_reset_done;
+    static int clksrc_table[9] =
+	/* reg 11: 0x50 = BRG, 0x00 = RTxC, 0x28 = TRxC */
+    	{ 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00 };
+    static int brgsrc_table[9] =
+	/* reg 14: 0 = RTxC, 2 = PCLK */
+    	{ 2, 2, 2, 2, 2, 2, 0, 2, 2 };
+    static int clkmode_table[9] =
+	/* reg 4: 0x40 = x16, 0x80 = x32, 0xc0 = x64 */
+    	{ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x80 };
+    static int div_table[9] =
+	/* reg12 (BRG low) */
+    	{ 208, 138, 103, 50, 24, 11, 1, 0, 0 };
+
+    int baud = cflag & CBAUD;
+    int clksrc, clkmode, div, reg3, reg5;
+    
+    if (cflag & CBAUDEX)
+	baud += B38400;
+    if (baud < B1200 || baud > B38400+2)
+	baud = B9600; /* use default 9600bps for non-implemented rates */
+    baud -= B1200; /* tables starts at 1200bps */
+
+    clksrc  = clksrc_table[baud];
+    clkmode = clkmode_table[baud];
+    div     = div_table[baud];
+    if (ATARIHW_PRESENT(TT_MFP) && baud >= 6) {
+	/* special treatment for TT, where rates >= 38400 are done via TRxC */
+	clksrc = 0x28; /* TRxC */
+	clkmode = baud == 6 ? 0xc0 :
+		  baud == 7 ? 0x80 : /* really 76800bps */
+			      0x40;  /* really 153600bps */
+	div = 0;
+    }
+
+    reg3 = (cflag & CSIZE) == CS8 ? 0xc0 : 0x40;
+    reg5 = (cflag & CSIZE) == CS8 ? 0x60 : 0x20 | 0x82 /* assert DTR/RTS */;
+    
+    (void)scc.cha_b_ctrl;	/* reset reg pointer */
+    SCC_WRITE( 9, 0xc0 );	/* reset */
+    LONG_DELAY();		/* extra delay after WR9 access */
+    SCC_WRITE( 4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03) : 0 |
+		  0x04 /* 1 stopbit */ |
+		  clkmode );
+    SCC_WRITE( 3, reg3 );
+    SCC_WRITE( 5, reg5 );
+    SCC_WRITE( 9, 0 );		/* no interrupts */
+    LONG_DELAY();		/* extra delay after WR9 access */
+    SCC_WRITE( 10, 0 );		/* NRZ mode */
+    SCC_WRITE( 11, clksrc );	/* main clock source */
+    SCC_WRITE( 12, div );	/* BRG value */
+    SCC_WRITE( 13, 0 );		/* BRG high byte */
+    SCC_WRITE( 14, brgsrc_table[baud] );
+    SCC_WRITE( 14, brgsrc_table[baud] | (div ? 1 : 0) );
+    SCC_WRITE( 3, reg3 | 1 );
+    SCC_WRITE( 5, reg5 | 8 );
+    
+    atari_SCC_reset_done = 1;
+    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(void atari_debug_init(void))
+{
+#ifdef CONFIG_KGDB
+    /* the m68k_debug_device is used by the GDB stub, do nothing here */
+    return;
+#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" );
+
+    }
+
+    if (!strcmp( m68k_debug_device, "ser1" )) {
+	/* ST-MFP Modem1 serial port */
+	atari_init_mfp_port( B9600|CS8 );
+	atari_console_driver.write = atari_mfp_console_write;
+    }
+    else if (!strcmp( m68k_debug_device, "ser2" )) {
+	/* SCC Modem2 serial port */
+	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 */
+	sound_ym.rd_data_reg_sel = 7;  /* select mixer control */
+	sound_ym.wd_data = 0xff;       /* sound off, ports are output */
+	sound_ym.rd_data_reg_sel = 15; /* select port B */
+	sound_ym.wd_data = 0;          /* no char */
+	sound_ym.rd_data_reg_sel = 14; /* select port A */
+	sound_ym.wd_data = sound_ym.rd_data_reg_sel | 0x20; /* strobe H */
+	atari_console_driver.write = atari_par_console_write;
+    }
+    if (atari_console_driver.write)
+	register_console(&atari_console_driver);
+}
+
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  tab-width: 8
+ * End:
+ */
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.72.orig/arch/m68k/atari/time.c linux-2.1.72/arch/m68k/atari/time.c
--- linux-2.1.72.orig/arch/m68k/atari/time.c	Thu Jan  1 01:00:00 1970
+++ linux-2.1.72/arch/m68k/atari/time.c	Thu Dec 18 16:03:53 1997
@@ -0,0 +1,416 @@
+/*
+ * linux/arch/m68k/atari/time.c
+ *
+ * Atari time and real time clock stuff
+ *
+ * Assembled of parts of former atari/config.c 97-12-18 by Roman Hodek
+ *  
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/mc146818rtc.h>
+#include <linux/kd.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+
+
+__initfunc(void
+atari_sched_init(void (*timer_routine)(int, void *, struct pt_regs *)))
+{
+    /* set Timer C data Register */
+    mfp.tim_dt_c = INT_TICKS;
+    /* start timer C, div = 1:100 */
+    mfp.tim_ct_cd = (mfp.tim_ct_cd & 15) | 0x60; 
+    /* install interrupt service routine for MFP Timer C */
+    request_irq(IRQ_MFP_TIMC, timer_routine, IRQ_TYPE_SLOW,
+                "timer", timer_routine);
+}
+
+/* ++andreas: gettimeoffset fixed to check for pending interrupt */
+
+#define TICK_SIZE 10000
+  
+/* This is always executed with interrupts disabled.  */
+unsigned long atari_gettimeoffset (void)
+{
+  unsigned long ticks, offset = 0;
+
+  /* read MFP timer C current value */
+  ticks = mfp.tim_dt_c;
+  /* The probability of underflow is less than 2% */
+  if (ticks > INT_TICKS - INT_TICKS / 50)
+    /* Check for pending timer interrupt */
+    if (mfp.int_pn_b & (1 << 5))
+      offset = TICK_SIZE;
+
+  ticks = INT_TICKS - ticks;
+  ticks = ticks * 10000L / INT_TICKS;
+
+  return ticks + offset;
+}
+
+
+static void mste_read(struct MSTE_RTC *val)
+{
+#define COPY(v) val->v=(mste_rtc.v & 0xf)
+	do {
+		COPY(sec_ones) ; COPY(sec_tens) ; COPY(min_ones) ; 
+		COPY(min_tens) ; COPY(hr_ones) ; COPY(hr_tens) ; 
+		COPY(weekday) ; COPY(day_ones) ; COPY(day_tens) ; 
+		COPY(mon_ones) ; COPY(mon_tens) ; COPY(year_ones) ;
+		COPY(year_tens) ;
+	/* prevent from reading the clock while it changed */
+	} while (val->sec_ones != (mste_rtc.sec_ones & 0xf));
+#undef COPY
+}
+
+static void mste_write(struct MSTE_RTC *val)
+{
+#define COPY(v) mste_rtc.v=val->v
+	do {
+		COPY(sec_ones) ; COPY(sec_tens) ; COPY(min_ones) ; 
+		COPY(min_tens) ; COPY(hr_ones) ; COPY(hr_tens) ; 
+		COPY(weekday) ; COPY(day_ones) ; COPY(day_tens) ; 
+		COPY(mon_ones) ; COPY(mon_tens) ; COPY(year_ones) ;
+		COPY(year_tens) ;
+	/* prevent from writing the clock while it changed */
+	} while (val->sec_ones != (mste_rtc.sec_ones & 0xf));
+#undef COPY
+}
+
+#define	RTC_READ(reg)				\
+    ({	unsigned char	__val;			\
+		outb(reg,&tt_rtc.regsel);	\
+		__val = tt_rtc.data;		\
+		__val;				\
+	})
+
+#define	RTC_WRITE(reg,val)			\
+    do {					\
+		outb(reg,&tt_rtc.regsel);	\
+		tt_rtc.data = (val);		\
+	} while(0)
+
+
+void atari_mste_gettod (int *yearp, int *monp, int *dayp,
+			int *hourp, int *minp, int *secp)
+{
+    int hr24=0, hour;
+    struct MSTE_RTC val;
+
+    mste_rtc.mode=(mste_rtc.mode | 1);
+    hr24=mste_rtc.mon_tens & 1;
+    mste_rtc.mode=(mste_rtc.mode & ~1);
+
+    mste_read(&val);
+    *secp = val.sec_ones + val.sec_tens * 10;
+    *minp = val.min_ones + val.min_tens * 10;
+    hour = val.hr_ones + val.hr_tens * 10;
+    if (!hr24) {
+        if (hour == 12 || hour == 12 + 20)
+	    hour -= 12;
+	if (hour >= 20)
+	    hour += 12 - 20;
+    }
+    *hourp = hour;
+    *dayp = val.day_ones + val.day_tens * 10;
+    *monp = val.mon_ones + val.mon_tens * 10;
+    *yearp = val.year_ones + val.year_tens * 10 + 80;	
+}
+
+  
+void atari_tt_gettod (int *yearp, int *monp, int *dayp,
+		      int *hourp, int *minp, int *secp)
+{
+    unsigned char	ctrl;
+    int hour, pm;
+
+    while (!(RTC_READ(RTC_FREQ_SELECT) & RTC_UIP)) ;
+    while (RTC_READ(RTC_FREQ_SELECT) & RTC_UIP) ;
+
+    *secp  = RTC_READ(RTC_SECONDS);
+    *minp  = RTC_READ(RTC_MINUTES);
+    hour = RTC_READ(RTC_HOURS);
+    *dayp  = RTC_READ(RTC_DAY_OF_MONTH);
+    *monp  = RTC_READ(RTC_MONTH);
+    *yearp = RTC_READ(RTC_YEAR);
+    pm = hour & 0x80;
+    hour &= ~0x80;
+
+    ctrl = RTC_READ(RTC_CONTROL); 
+
+    if (!(ctrl & RTC_DM_BINARY)) {
+        BCD_TO_BIN(*secp);
+        BCD_TO_BIN(*minp);
+        BCD_TO_BIN(hour);
+        BCD_TO_BIN(*dayp);
+        BCD_TO_BIN(*monp);
+        BCD_TO_BIN(*yearp);
+    }
+    if (!(ctrl & RTC_24H)) {
+	if (!pm && hour == 12)
+	    hour = 0;
+	else if (pm && hour != 12)
+            hour += 12;
+    }
+    *hourp = hour;
+
+    /* Adjust values (let the setup valid) */
+    *yearp += atari_rtc_year_offset;
+}
+
+#define HWCLK_POLL_INTERVAL	5
+
+int atari_mste_hwclk( int op, struct hwclk_time *t )
+{
+    int hour, year;
+    int hr24=0;
+    struct MSTE_RTC val;
+    
+    mste_rtc.mode=(mste_rtc.mode | 1);
+    hr24=mste_rtc.mon_tens & 1;
+    mste_rtc.mode=(mste_rtc.mode & ~1);
+
+    if (op) {
+        /* write: prepare values */
+        
+        val.sec_ones = t->sec % 10;
+        val.sec_tens = t->sec / 10;
+        val.min_ones = t->min % 10;
+        val.min_tens = t->min / 10;
+        hour = t->hour;
+        if (!hr24) {
+	    if (hour > 11)
+		hour += 20 - 12;
+	    if (hour == 0 || hour == 20)
+		hour += 12;
+        }
+        val.hr_ones = hour % 10;
+        val.hr_tens = hour / 10;
+        val.day_ones = t->day % 10;
+        val.day_tens = t->day / 10;
+        val.mon_ones = (t->mon+1) % 10;
+        val.mon_tens = (t->mon+1) / 10;
+        year = t->year - 80;
+        val.year_ones = year % 10;
+        val.year_tens = year / 10;
+        val.weekday = t->wday;
+        mste_write(&val);
+        mste_rtc.mode=(mste_rtc.mode | 1);
+        val.year_ones = (year % 4);	/* leap year register */
+        mste_rtc.mode=(mste_rtc.mode & ~1);
+    }
+    else {
+        mste_read(&val);
+        t->sec = val.sec_ones + val.sec_tens * 10;
+        t->min = val.min_ones + val.min_tens * 10;
+        hour = val.hr_ones + val.hr_tens * 10;
+	if (!hr24) {
+	    if (hour == 12 || hour == 12 + 20)
+		hour -= 12;
+	    if (hour >= 20)
+                hour += 12 - 20;
+        }
+	t->hour = hour;
+	t->day = val.day_ones + val.day_tens * 10;
+        t->mon = val.mon_ones + val.mon_tens * 10 - 1;
+        t->year = val.year_ones + val.year_tens * 10 + 80;
+        t->wday = val.weekday;
+    }
+    return 0;
+}
+
+int atari_tt_hwclk( int op, struct hwclk_time *t )
+{
+    int sec=0, min=0, hour=0, day=0, mon=0, year=0, wday=0; 
+    unsigned long 	flags;
+    unsigned char	ctrl;
+    int pm = 0;
+
+    ctrl = RTC_READ(RTC_CONTROL); /* control registers are
+                                   * independent from the UIP */
+
+    if (op) {
+        /* write: prepare values */
+        
+        sec  = t->sec;
+        min  = t->min;
+        hour = t->hour;
+        day  = t->day;
+        mon  = t->mon + 1;
+        year = t->year - atari_rtc_year_offset;
+        wday = t->wday + (t->wday >= 0);
+        
+        if (!(ctrl & RTC_24H)) {
+	    if (hour > 11) {
+		pm = 0x80;
+		if (hour != 12)
+		    hour -= 12;
+	    }
+	    else if (hour == 0)
+		hour = 12;
+        }
+        
+        if (!(ctrl & RTC_DM_BINARY)) {
+            BIN_TO_BCD(sec);
+            BIN_TO_BCD(min);
+            BIN_TO_BCD(hour);
+            BIN_TO_BCD(day);
+            BIN_TO_BCD(mon);
+            BIN_TO_BCD(year);
+            if (wday >= 0) BIN_TO_BCD(wday);
+        }
+    }
+    
+    /* Reading/writing the clock registers is a bit critical due to
+     * the regular update cycle of the RTC. While an update is in
+     * progress, registers 0..9 shouldn't be touched.
+     * The problem is solved like that: If an update is currently in
+     * progress (the UIP bit is set), the process sleeps for a while
+     * (50ms). This really should be enough, since the update cycle
+     * normally needs 2 ms.
+     * If the UIP bit reads as 0, we have at least 244 usecs until the
+     * update starts. This should be enough... But to be sure,
+     * additionally the RTC_SET bit is set to prevent an update cycle.
+     */
+
+    while( RTC_READ(RTC_FREQ_SELECT) & RTC_UIP ) {
+        current->state = TASK_INTERRUPTIBLE;
+        current->timeout = jiffies + HWCLK_POLL_INTERVAL;
+        schedule();
+    }
+
+    save_flags(flags);
+    cli();
+    RTC_WRITE( RTC_CONTROL, ctrl | RTC_SET );
+    if (!op) {
+        sec  = RTC_READ( RTC_SECONDS );
+        min  = RTC_READ( RTC_MINUTES );
+        hour = RTC_READ( RTC_HOURS );
+        day  = RTC_READ( RTC_DAY_OF_MONTH );
+        mon  = RTC_READ( RTC_MONTH );
+        year = RTC_READ( RTC_YEAR );
+        wday = RTC_READ( RTC_DAY_OF_WEEK );
+    }
+    else {
+        RTC_WRITE( RTC_SECONDS, sec );
+        RTC_WRITE( RTC_MINUTES, min );
+        RTC_WRITE( RTC_HOURS, hour + pm);
+        RTC_WRITE( RTC_DAY_OF_MONTH, day );
+        RTC_WRITE( RTC_MONTH, mon );
+        RTC_WRITE( RTC_YEAR, year );
+        if (wday >= 0) RTC_WRITE( RTC_DAY_OF_WEEK, wday );
+    }
+    RTC_WRITE( RTC_CONTROL, ctrl & ~RTC_SET );
+    restore_flags(flags);
+
+    if (!op) {
+        /* read: adjust values */
+        
+        if (hour & 0x80) {
+	    hour &= ~0x80;
+	    pm = 1;
+	}
+
+	if (!(ctrl & RTC_DM_BINARY)) {
+            BCD_TO_BIN(sec);
+            BCD_TO_BIN(min);
+            BCD_TO_BIN(hour);
+            BCD_TO_BIN(day);
+            BCD_TO_BIN(mon);
+            BCD_TO_BIN(year);
+            BCD_TO_BIN(wday);
+        }
+
+        if (!(ctrl & RTC_24H)) {
+	    if (!pm && hour == 12)
+		hour = 0;
+	    else if (pm && hour != 12)
+		hour += 12;
+        }
+
+        t->sec  = sec;
+        t->min  = min;
+        t->hour = hour;
+        t->day  = day;
+        t->mon  = mon - 1;
+        t->year = year + atari_rtc_year_offset;
+        t->wday = wday - 1;
+    }
+
+    return( 0 );
+}
+
+
+int atari_mste_set_clock_mmss (unsigned long nowtime)
+{
+    short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
+    struct MSTE_RTC val;
+    unsigned char rtc_minutes;
+
+    mste_read(&val);  
+    rtc_minutes= val.min_ones + val.min_tens * 10;
+    if ((rtc_minutes < real_minutes
+         ? real_minutes - rtc_minutes
+         : rtc_minutes - real_minutes) < 30)
+    {
+        val.sec_ones = real_seconds % 10;
+        val.sec_tens = real_seconds / 10;
+        val.min_ones = real_minutes % 10;
+        val.min_tens = real_minutes / 10;
+        mste_write(&val);
+    }
+    else
+        return -1;
+    return 0;
+}
+
+int atari_tt_set_clock_mmss (unsigned long nowtime)
+{
+    int retval = 0;
+    short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
+    unsigned char save_control, save_freq_select, rtc_minutes;
+
+    save_control = RTC_READ (RTC_CONTROL); /* tell the clock it's being set */
+    RTC_WRITE (RTC_CONTROL, save_control | RTC_SET);
+
+    save_freq_select = RTC_READ (RTC_FREQ_SELECT); /* stop and reset prescaler */
+    RTC_WRITE (RTC_FREQ_SELECT, save_freq_select | RTC_DIV_RESET2);
+
+    rtc_minutes = RTC_READ (RTC_MINUTES);
+    if (!(save_control & RTC_DM_BINARY))
+        BCD_TO_BIN (rtc_minutes);
+
+    /* Since we're only adjusting minutes and seconds, don't interfere
+       with hour overflow.  This avoids messing with unknown time zones
+       but requires your RTC not to be off by more than 30 minutes.  */
+    if ((rtc_minutes < real_minutes
+         ? real_minutes - rtc_minutes
+         : rtc_minutes - real_minutes) < 30)
+        {
+            if (!(save_control & RTC_DM_BINARY))
+                {
+                    BIN_TO_BCD (real_seconds);
+                    BIN_TO_BCD (real_minutes);
+                }
+            RTC_WRITE (RTC_SECONDS, real_seconds);
+            RTC_WRITE (RTC_MINUTES, real_minutes);
+        }
+    else
+        retval = -1;
+
+    RTC_WRITE (RTC_FREQ_SELECT, save_freq_select);
+    RTC_WRITE (RTC_CONTROL, save_control);
+    return retval;
+}
+
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  tab-width: 8
+ * End:
+ */
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.72.orig/arch/m68k/kernel/setup.c linux-2.1.72/arch/m68k/kernel/setup.c
--- linux-2.1.72.orig/arch/m68k/kernel/setup.c	Thu Dec 18 13:14:32 1997
+++ linux-2.1.72/arch/m68k/kernel/setup.c	Thu Dec 18 13:23:33 1997
@@ -79,6 +79,10 @@
 void (*mach_floppy_setup) (char *, int *) __initdata = NULL;
 void (*mach_floppy_eject) (void) = NULL;
 #endif
+#ifdef CONFIG_HEARTBEAT
+void (*mach_heartbeat) (int) = NULL;
+int mach_heartbeat_irq;
+#endif
 
 extern void base_trap_init(void);
 
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.72.orig/arch/m68k/kernel/time.c linux-2.1.72/arch/m68k/kernel/time.c
--- linux-2.1.72.orig/arch/m68k/kernel/time.c	Tue Dec 16 16:20:09 1997
+++ linux-2.1.72/arch/m68k/kernel/time.c	Thu Dec 18 15:48:58 1997
@@ -19,16 +19,7 @@
 
 #ifdef CONFIG_HEARTBEAT
 #include <linux/kernel_stat.h>
-#include <asm/setup.h>
-#ifdef CONFIG_AMIGA
-#include <asm/amigahw.h>
-#include <asm/amigaints.h>
 #endif
-#ifdef CONFIG_ATARI
-#include <asm/atarihw.h>
-#include <asm/atariints.h>
-#endif
-#endif /* CONFIG_HEARTBEAT */
 
 #include <linux/timex.h>
 
@@ -89,40 +80,18 @@
 	/* use power LED as a heartbeat instead -- much more useful
 	   for debugging -- based on the version for PReP by Cort */
 	/* acts like an actual heart beat -- ie thump-thump-pause... */
-#ifdef CONFIG_AMIGA
-	if (MACH_IS_AMIGA) {
-	    switch(kstat.interrupts[SYS_IRQS + IRQ_AMIGA_CIAB_TA] % 101) {
-		case 0:
-		case 20:
-		    ciaa.pra &= ~2;
-		    break;
-		case 7:
-		case 27:
-		    ciaa.pra |= 2;
-		    break;
-	    }
-        }
-#endif
-#ifdef CONFIG_ATARI
-	if (MACH_IS_ATARI && !atari_dont_touch_floppy_select) {
-	    unsigned long flags, tmp;
-	    save_flags(flags);
-	    cli();
-	    sound_ym.rd_data_reg_sel = 14; /* Select PSG Port A */
-	    tmp = sound_ym.rd_data_reg_sel;
-	    switch(kstat.interrupts[IRQ_MFP_TIMC] % 101) {
+	if (mach_heartbeat) {
+	    switch(kstat.interrupts[mach_heartbeat_irq] % 101) {
 	      case 0:
 	      case 20:
-		sound_ym.wd_data = tmp & ~0x02;
+		mach_heartbeat( 1 );
 		break;
 	      case 7:
 	      case 27:
-		sound_ym.wd_data = tmp | 0x02;
+		mach_heartbeat( 0 );
 		break;
 	    }
-	    restore_flags(flags);
-        }
-#endif
+	}
 #endif /* CONFIG_HEARTBEAT */
 }
 
Binary files linux-2.1.72.orig/drivers/sound/configure and linux-2.1.72/drivers/sound/configure differ
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.72.orig/include/asm-m68k/machdep.h linux-2.1.72/include/asm-m68k/machdep.h
--- linux-2.1.72.orig/include/asm-m68k/machdep.h	Thu Dec 18 13:14:45 1997
+++ linux-2.1.72/include/asm-m68k/machdep.h	Thu Dec 18 13:23:20 1997
@@ -35,6 +35,8 @@
 extern long mach_max_dma_address;
 extern void (*mach_floppy_setup)(char *, int *);
 extern void (*mach_floppy_eject)(void);
+extern void (*mach_heartbeat) (int);
+extern int mach_heartbeat_irq;
 extern int mach_sysrq_key;
 extern int mach_sysrq_shift_state;
 extern int mach_sysrq_shift_mask;
