diff -rc linux/Makefile linux.1.3.79/Makefile *** linux/Makefile Mon Mar 25 05:55:08 1996 --- linux.1.3.79/Makefile Mon Apr 1 22:53:07 1996 *************** *** 147,152 **** --- 147,156 ---- DRIVERS := $(DRIVERS) drivers/sound/sound.a endif + ifdef CONFIG_PCSP + DRIVERS := $(DRIVERS) drivers/pcsnd/pcsp.a + endif + ifdef CONFIG_PCI DRIVERS := $(DRIVERS) drivers/pci/pci.a endif *************** *** 324,329 **** --- 328,334 ---- mrproper: clean rm -f include/linux/autoconf.h include/linux/version.h rm -f drivers/sound/local.h drivers/sound/.defines + rm -f drivers/pcsp/local.h rm -f drivers/scsi/aic7xxx_asm drivers/scsi/aic7xxx_seq.h rm -f drivers/char/uni_hash.tbl drivers/char/conmakehash rm -f .version .config* config.in config.old diff -rc linux/arch/i386/config.in linux.1.3.79/arch/i386/config.in *** linux/arch/i386/config.in Mon Feb 26 04:58:03 1996 --- linux.1.3.79/arch/i386/config.in Mon Apr 1 23:03:35 1996 *************** *** 92,97 **** --- 92,101 ---- if [ "$CONFIG_SOUND" != "n" ]; then source drivers/sound/Config.in fi + bool 'PC-Speaker audio driver support' CONFIG_PCSP + if [ "$CONFIG_PCSP" = "y" ]; then + bool 'compile PC-Speaker driver as a module' CONFIG_PCSP_MODULE + fi endmenu mainmenu_option next_comment diff -rc linux/arch/i386/kernel/irq.c linux.1.3.79/arch/i386/kernel/irq.c *** linux/arch/i386/kernel/irq.c Sun Mar 17 02:01:02 1996 --- linux.1.3.79/arch/i386/kernel/irq.c Tue Apr 2 19:14:36 1996 *************** *** 23,28 **** --- 23,29 ---- #include #include #include + #include #include #include *************** *** 549,551 **** --- 550,658 ---- setup_x86_irq(2, &irq2); setup_x86_irq(13, &irq13); } + + #ifdef CONFIG_PCSP + /* + * /dev/pcsp implementation, part of linux/arch/i386/kernel/irq.c + * + * Copyright (C) 1993, 1994 Michael Beck + */ + + static int (*pcsp_IRQ)(void) = NULL; + static const char *pcsp_irq0_owner = NULL; + + /* + * This is a mix of a fast and a slow interrupt; + * pcsp_IRQ is called like a fast int, if it returns a 0, + * the original (slow) handler is started + */ + extern void FAST_timer_irq(void); + __asm__( + "\n"__ALIGN_STR"\n" + SYMBOL_NAME_STR(FAST_timer_irq)":\n\t" + SAVE_MOST + ACK_FIRST(0x01) + "incl "SYMBOL_NAME_STR(intr_count)"\n\t" + "sti\n\t" + "call *"SYMBOL_NAME_STR(pcsp_IRQ)"\n\t" + "cmpl $0,%eax\n\t" + "je 9f\n\t" + "cli\n\t" + UNBLK_FIRST(0x01) + "decl "SYMBOL_NAME_STR(intr_count)"\n\t" + RESTORE_MOST + + "\n"__ALIGN_STR"\n" + "9:\t" /* call the original do_IRQ */ + "popl %ecx\n\t" + "popl %edx\n\t" + "popl %eax\n\t" + "pop %ds\n\t" + "pop %es\n\t" + + "pushl $-2\n\t" /* we know this is IRQ0 */ + SAVE_ALL + "movl %esp,%ebx\n\t" + "pushl %ebx\n\t" + "pushl $0\n\t" + "call "SYMBOL_NAME_STR(do_IRQ)"\n\t" + "addl $8,%esp\n\t" + "cli\n\t" + UNBLK_FIRST(0x01) + "decl "SYMBOL_NAME_STR(intr_count)"\n\t" + "jmp ret_from_sys_call\n" + ); + + /* + * Set the function func to be executed as fast-timer-int; + * if func returns a 0, the old IRQ0-handler is called + * This is only allowed if IRQ0 was a former SLOW-int; + * should be no problem because do_timer() use it normally :-) + */ + int pcsp_set_irq(int (*func)(void)) + { + unsigned long flags; + + /* + * Ok, another problem. Since 1.3.14, some things have changed, like the + * definition of irq_action. I'm no expert on this strategy, but i tried + * to solve this problem based in what i think MB is trying to do here.. + * comments welcome. Erick. + */ + pcsp_IRQ = func; + if (! pcsp_IRQ) + return -EINVAL; + if (! irq_action[0]) + return -EINVAL; + if (! irq_action[0]->name) + return -EINVAL; + if (irq_action[0]->flags & SA_INTERRUPT) + return -EBUSY; + pcsp_irq0_owner = irq_action[0]->name; + irq_action[0]->name = "pcsp+timer"; + save_flags(flags); + cli(); + set_intr_gate(0x20, FAST_timer_irq); + restore_flags(flags); + return 0; + } + + /* + * reset the IRQ0 to default handling (a SLOW-int) + */ + int pcsp_release_irq(void) + { + unsigned long flags; + + if (! pcsp_IRQ) + return -EINVAL; + save_flags(flags); + cli(); + set_intr_gate(0x20, interrupt[0]); + restore_flags(flags); + pcsp_IRQ = NULL; + irq_action[0]->name = pcsp_irq0_owner; + return 0; + } + #endif + diff -rc linux/arch/i386/kernel/time.c linux.1.3.79/arch/i386/kernel/time.c *** linux/arch/i386/kernel/time.c Sun Mar 17 01:54:33 1996 --- linux.1.3.79/arch/i386/kernel/time.c Tue Apr 2 19:15:36 1996 *************** *** 116,122 **** --- 116,130 ---- */ #define TICK_SIZE tick + #ifdef CONFIG_PCSP + extern int pcsp_clockticks,pcsp_timer0_latch; + #endif + /* PCSP note: I modified the do_slow_gettimeoffset function, guided by + * MB's patch. I know, i know. What'll happen if time_init sets + * do_gettimeoffset to do_fast_gettimeoffset (on Pentiums?) ????...ask + * Michael.....HELP!. Erick + */ static unsigned long do_slow_gettimeoffset(void) { int count; *************** *** 126,131 **** --- 134,142 ---- outb_p(0x00, 0x43); /* latch the count ASAP */ count = inb_p(0x40); /* read the latched count */ count |= inb(0x40) << 8; + #ifdef CONFIG_PCSP + count += pcsp_clockticks - pcsp_timer0_latch; + #endif /* we know probability of underflow is always MUCH less than 1% */ if (count > (LATCH - LATCH/100)) { /* check for pending timer interrupt */ diff -rc linux/drivers/Makefile linux.1.3.79/drivers/Makefile *** linux/drivers/Makefile Mon Feb 26 04:58:04 1996 --- linux.1.3.79/drivers/Makefile Wed Apr 3 09:21:08 1996 *************** *** 34,39 **** --- 34,47 ---- endif endif + ifeq ($(CONFIG_PCSP),y) + SUB_DIRS += pcsnd + endif + + ifeq ($(CONFIG_PCSP_MODULE),y) + MOD_SUB_DIRS += pcsnd + endif + ifdef CONFIG_CD_NO_IDESCSI SUB_DIRS += cdrom MOD_SUB_DIRS += cdrom diff -rc linux/drivers/char/mem.c linux.1.3.79/drivers/char/mem.c *** linux/drivers/char/mem.c Thu Mar 7 08:59:02 1996 --- linux.1.3.79/drivers/char/mem.c Tue Apr 2 19:10:58 1996 *************** *** 29,34 **** --- 29,37 ---- #ifdef CONFIG_ISDN void isdn_init(void); #endif + #ifdef CONFIG_PCSP + long pcsp_init(long); + #endif static int read_ram(struct inode * inode, struct file * file, char * buf, int count) { *************** *** 380,385 **** --- 383,389 ---- int chr_dev_init(void) { + long mem_start; if (register_chrdev(MEM_MAJOR,"mem",&memory_fops)) printk("unable to get major %d for memory devs\n", MEM_MAJOR); rand_initialize(); *************** *** 400,405 **** --- 404,417 ---- #endif #if CONFIG_ISDN isdn_init(); + #endif + /* I don't know what's the deal with mem_start on older kernels, so i + * decided to allocate 24 bytes, and pass this so pcsp.buffer would point + * to this space...I hope it doesn't bring side effects. Erick + */ + #ifdef CONFIG_PCSP + mem_start=(long)kmalloc(24,GFP_KERNEL); + kfree((void*)pcsp_init(mem_start)); #endif #ifdef CONFIG_FTAPE ftape_init(); diff -rc linux/drivers/char/vt.c linux.1.3.79/drivers/char/vt.c *** linux/drivers/char/vt.c Sat Feb 17 03:19:07 1996 --- linux.1.3.79/drivers/char/vt.c Tue Apr 2 19:12:28 1996 *************** *** 8,13 **** --- 8,14 ---- * Restrict VT switching via ioctl() - grif@cs.ucr.edu - Dec 1995 */ + #include #include #include #include *************** *** 147,155 **** --- 148,165 ---- * We also return immediately, which is what was implied within the X * comments - KDMKTONE doesn't put the process to sleep. */ + + #ifdef CONFIG_PCSP + extern char pcsp_speaker; + #endif + static void kd_nosound(unsigned long ignored) { + #ifdef CONFIG_PCSP + /* can't allow usage of counter 2 if /dev/pcsp uses it */ + if (! pcsp_speaker) + #endif /* disable counter 2 */ outb(inb_p(0x61)&0xFC, 0x61); return; *************** *** 166,171 **** --- 176,185 ---- if (hz > 20 && hz < 32767) count = 1193180 / hz; + #ifdef CONFIG_PCSP + /* can't allow usage of counter 2 if /dev/pcsp uses it */ + if (! pcsp_speaker) { + #endif cli(); del_timer(&sound_timer); if (count) { *************** *** 184,189 **** --- 198,206 ---- } else kd_nosound(0); sti(); + #ifdef CONFIG_PCSP + } + #endif return; } diff -rc linux/drivers/pcsnd/pcsndriv.c linux.1.3.79/drivers/pcsnd/pcsndriv.c *** linux/drivers/pcsnd/pcsndriv.c Sat Aug 5 11:59:09 1995 --- linux.1.3.79/drivers/pcsnd/pcsndriv.c Tue Apr 2 19:04:08 1996 *************** *** 22,35 **** #include #include - #ifdef MODULE - #include - #include - #include - #else #define MOD_INC_USE_COUNT #define MOD_DEC_USE_COUNT - #endif #include "tables.h" --- 22,29 ---- *************** *** 80,86 **** extern int pcsp_set_irq(int (*func)(void)); extern int pcsp_release_irq(void); ! extern void do_timer(int irq, struct pt_regs * regs); static void pcsp_stop_timer(void); /* test if a parallel port is free */ --- 74,82 ---- extern int pcsp_set_irq(int (*func)(void)); extern int pcsp_release_irq(void); ! /* Oops, in 1.3.79, do_timer changed a bit.....Erick */ ! ! extern void do_timer(struct pt_regs * regs); static void pcsp_stop_timer(void); /* test if a parallel port is free */ diff -rc linux/drivers/pcsnd/pcsp.c linux.1.3.79/drivers/pcsnd/pcsp.c *** linux/drivers/pcsnd/pcsp.c Sat Aug 5 11:59:20 1995 --- linux.1.3.79/drivers/pcsnd/pcsp.c Tue Apr 2 19:03:04 1996 *************** *** 67,74 **** #ifdef MODULE - char kernel_version[] = UTS_RELEASE; - int init_module(void) { int minor, major, err; --- 67,72 ---- diff -rc linux/drivers/pcsnd/pcsp_mixer.c linux.1.3.79/drivers/pcsnd/pcsp_mixer.c *** linux/drivers/pcsnd/pcsp_mixer.c Sat Aug 5 11:30:17 1995 --- linux.1.3.79/drivers/pcsnd/pcsp_mixer.c Tue Apr 2 19:03:40 1996 *************** *** 21,34 **** #include #include - #ifdef MODULE - #include - #include - #include - #else #define MOD_INC_USE_COUNT #define MOD_DEC_USE_COUNT - #endif #define IOCTL_FROM_USER(d, s, o, c) memcpy_fromfs((d), &((s)[o]), (c)) #define IOCTL_TO_USER(d, o, s, c) memcpy_tofs(&((d)[o]), (s), (c)) --- 21,28 ---- diff -rc linux/init/main.c linux.1.3.79/init/main.c *** linux/init/main.c Mon Mar 25 01:58:23 1996 --- linux.1.3.79/init/main.c Mon Apr 1 22:25:51 1996 *************** *** 87,92 **** --- 87,95 ---- extern void ppa_setup(char *str, int *ints); extern void scsi_luns_setup(char *str, int *ints); extern void sound_setup(char *str, int *ints); + #ifdef CONFIG_PCSP + extern void pcsp_setup(char *str,int *ints); + #endif #ifdef CONFIG_CDU31A extern void cdu31a_setup(char *str, int *ints); #endif CONFIG_CDU31A *************** *** 328,333 **** --- 331,339 ---- #endif CONFIG_ISP16_CDI #ifdef CONFIG_SOUND { "sound=", sound_setup }, + #endif + #ifdef CONFIG_PCSP + { "pcsp=", pcsp_setup }, #endif #ifdef CONFIG_ISDN_DRV_ICN { "icn=", icn_setup }, diff -rc linux/kernel/ksyms.c linux.1.3.79/kernel/ksyms.c *** linux/kernel/ksyms.c Tue Mar 26 04:40:22 1996 --- linux.1.3.79/kernel/ksyms.c Tue Apr 2 19:13:22 1996 *************** *** 62,67 **** --- 62,70 ---- #ifdef __SMP__ #include #endif + #ifdef CONFIG_PCSP + #include + #endif extern char *get_options(char *str, int *ints); extern void set_device_ro(int dev,int flag); *************** *** 358,363 **** --- 361,378 ---- /* bimfm_aout */ X(get_write_access), X(put_write_access), + #ifdef CONFIG_PCSP + X(pcsp_timer0_latch), + X(pcsp_clockticks), + #ifdef CONFIG_PCSP_MODULE + X(pcsp_enabled), + X(pcsp_active), + X(pcsp_speaker), + X(pcsp), + X(pcsp_set_irq), + X(pcsp_release_irq), + #endif + #endif /******************************************************** * Do not add anything below this line, diff -rc linux/scripts/Configure linux.1.3.79/scripts/Configure *** linux/scripts/Configure Mon Mar 25 01:58:28 1996 --- linux.1.3.79/scripts/Configure Mon Apr 1 23:04:58 1996 *************** *** 462,467 **** --- 462,470 ---- mv .tmpconfig .config mv .tmpconfig.h include/linux/autoconf.h + if [ "$CONFIG_PCSP" = "y" ] ; then + $MAKE -C drivers/pcsnd config || exit 1 + fi echo echo "The linux kernel is now hopefully configured for your setup." echo "Check the top-level Makefile for additional configuration,"