This is next56.c in view mode; [Download] [Up]
/* 56000 - nExt communication */ /* compiled: cc next56.c -c -O */ /* changed relatively drastically during Feb-94 for port to Intel and so on * Main change: TRDY => TXDE at DAJ's request to make future device drivers simpler * (the MusicKit uses TXDE, I originally used TRDY) * Related change: removed all "l" series functions -- these were debugging conveniences * Also: removed calls on DSPOpenNoBoot and DSPClose and substituted lower level snddriver calls. */ #include "clmdsp.h" /* dsp.h and hostInterface declaration */ #include <sound/sound.h> #include <sound/sounddriver.h> #include <mach/mach.h> #include <sys/file.h> #include <sys/mman.h> /* protection bits etc */ /* for a Turbo NeXT, delete the word "inline" here and in get_cpu_rx below */ inline put_cpu_tx(int x) { #ifdef ARIEL_PC_56D unsigned char hi = (x >> 16); unsigned char med = ((x >> 8) & 0xff); unsigned char low = (x & 0xff); dsp_putTXRaw(current_active_dsp,hi,med,low); #else cpu_HI->data.tx.h = ((x >> 16) & 0xff); cpu_HI->data.tx.m = ((x >> 8) & 0xff); cpu_HI->data.tx.l = (x & 0xff); #endif } inline get_cpu_rx(int *x) { #ifdef ARIEL_PC_56D unsigned char hi,med,low; dsp_getRXRaw(current_active_dsp,&hi,&med,&low); *x = hi; *x = (*x << 8) | med; *x = (*x << 8) | low; #else /* byte-wise order should be high middle low (RXDF cleared when low read -- 10-23) */ *x = ((cpu_HI->data.rx.h) << 16); *x = *x | ((cpu_HI->data.rx.m) << 8); *x = *x | (cpu_HI->data.rx.l); #endif } static int dsp_fd = -1; /* "static" here apparently means "internal" */ #ifndef ARIEL_PC_56D static int current_active_dsp = -1; #endif int wait_time = 1000000; #ifndef ARIEL_PC_56D DSPRegs *getDSPRegs() /* from (system 1.0) /NextLibrary/Documentation/NeXT/SysRefMan/14_ProgDSP.wn */ /* not documented (or guaranteed to work) in system 2.0, but will work at least another year... */ /* see /usr/include/nextdev/snd_dspreg.h */ /* * The following function memory-maps the DSP host interface. * Memory-mapped access can interfere with the Mach Sound/DSP * driver, so normally the driver is kept unaware during * memory-mapped control by zeroing RREQ and TREQ in the * Interrupt Control Register (ICR) of the host interface; * this ensures that the DSP never interrupts the host, which * would cause the driver to read and possibly write the DSP. */ { char *alloc_addr; /* page address for DSP memory map */ dsp_fd = open("/dev/dsp",O_RDWR); /* need <sys/file.h> */ if (dsp_fd == -1) return(NULL); if (( alloc_addr = (char *)valloc(getpagesize()) ) == NULL) return(NULL); if ( -1 == mmap(alloc_addr, getpagesize(), /* Must map a full page */ PROT_READ|PROT_WRITE, /* rw access <sys/mman.h> */ MAP_SHARED, /* shared access (of course) */ dsp_fd, /* This device */ 0) ) /* 0 offset */ return(NULL); return (DSPRegs *)alloc_addr; /* <dsp/dsp_structs.h> */ } #endif /* the following are the indices to direct lisp (from C) function calls (a sort of case statement) */ #define SERVICE_BREAK 0 #define READ_INPUT 1 #define LOCSIZ_SERVICE_BREAK 2 #define AWAIT_GET_SERVICE_BREAK 3 #define AWAIT_PUT_SERVICE_BREAK 4 #define AWAIT_OUTPUT_SERVICE_BREAK 6 wait_a_while (int ticks) { int i; for (i=0;i<=ticks;i++); } cleararray(int beg, int end, int *arr) { int *i,*j; j=arr+end; /* C compiler on Next doesn't optimize these expressions out of the loop, so... */ for (i=arr+beg;i<=j;i++) *i=0; /* for (i=beg;i<=end;i++) arr[i]=0; */ } arrtran (int beg1, int end1, int *arr1, int beg2, int *arr2) { int *i,*j,*k; k=arr1+end1; for (i=arr1+beg1,j=arr2+beg2;i<=k;i++,j++) *j=*i; /* arr2[beg2 by j]=arr1[beg1 to end1 by i] */ } cloadfarr(float *tbl, int siz, int beg, int *mem) { int i,j,fix,exp23; exp23=8388608; /* 1 << 23 may be C's way of saying this */ for (i=0,j=beg;i<siz;i++,j++) { if (tbl[i] != 1.0) { fix=(tbl[i]*exp23); mem[j]=(fix & 0xffffff); } else mem[j]=0x7fffff; /* two's complement 24-bit max pos num -- "fractional" one */ } } /* Now some very unfortunate duplication of code -- in system 1.0 this was unnecessary */ /* -------------------------------------- AwaitData ---------------------------------- */ inline int Await_cpu_Data(int ms) { int i; if (CPU_ISR&1) return 0; i=0; while ((!(CPU_ISR&1)) && (i<ms)) ++i; if (CPU_ISR&1) return 0; return -1; } inline int Await_qp_Data(int ms) { int i; if (QP_ISR&1) return 0; i=0; while ((!(QP_ISR&1)) && (i<ms)) ++i; if (QP_ISR&1) return 0; return -1; } inline int AwaitData(int ms) { int i; i = 0; if (current_active_dsp != -1) { if (current_active_dsp == 0) i = Await_cpu_Data(ms); else i = Await_qp_Data(ms); } return i; } /* -------------------------------------- AwaitTRDY ---------------------------------- */ /* changed to TXDE at DAJ's request 16-Feb-94 */ inline int Await_cpu_TRDY(int ms) { int i; if (CPU_ISR&2) return 0; i=0; while ((!(CPU_ISR&2)) && (i<ms)) ++i; if (CPU_ISR&2) return 0; return -1; } inline int Await_qp_TRDY(int ms) { int i; if (QP_ISR&2) return 0; i=0; while ((!(QP_ISR&2)) && (i<ms)) ++i; if (QP_ISR&2) return 0; return -1; } inline int AwaitTRDY(int ms) { int i; i = 0; if (current_active_dsp != -1) { if (current_active_dsp == 0) i = Await_cpu_TRDY(ms); else i = Await_qp_TRDY(ms); } return i; } /* -------------------------------------- HF2 --------------------------------------- */ inline int cpu_HF2 (void) { return (CPU_ISR&8); } inline int qp_HF2 (void) { return (QP_ISR&8); } inline int HF2 (void) { int i; i = -1; if (current_active_dsp != -1) { if (current_active_dsp == 0) i = cpu_HF2(); else i = qp_HF2(); } return i; } /* -------------------------------------- HF3 --------------------------------------- */ inline int cpu_HF3 (void) { return (CPU_ISR&16); } inline int qp_HF3 (void) { return (QP_ISR&16); } inline int HF3 (void) { int i; i = -1; if (current_active_dsp != -1) { if (current_active_dsp == 0) i = cpu_HF3(); else i = qp_HF3(); } return i; } /* -------------------------------------- ISR et al ------------------------------------- */ int get_ISR (void) { int i; i = -1; if (current_active_dsp != -1) { if (current_active_dsp == 0) i = CPU_ISR; else i = QP_ISR; } return i; } int get_ICR (void) { int i; i = -1; if (current_active_dsp != -1) { if (current_active_dsp == 0) i = CPU_ICR; else i = QP_ICR; } return i; } int get_CVR (void) { int i; i = -1; if (current_active_dsp != -1) { if (current_active_dsp == 0) i = CPU_CVR; else i = QP_CVR; } return i; } put_CVR (int word) { if (current_active_dsp != -1) { if (current_active_dsp == 0) put_cpu_cvr(word); else put_qp_cvr(word); } } put_ICR (int word) { if (current_active_dsp != -1) { if (current_active_dsp == 0) put_cpu_icr(word); else put_qp_icr(word); } } /* -------------------------------------- checkHF3 ------------------------------------- */ int check_cpu_HF3 (void) { int i; long lisp_call(int index); if ((cpu_HF3() != 0) && (cpu_HF3() != 0)) { /* see Motorola DSP56000 manual section 10.2.6.5 -- when HF2 and 3 used as a pair (as here) */ /* you may see indeterminate states during a transition, so you have to read twice */ if ((cpu_HF2() == 0) && (cpu_HF2() == 0)) { i=0; while ((cpu_HF3() != 0) && (cpu_HF2() == 0) && (i<wait_time)) ++i; if ((cpu_HF2() == 0) && (cpu_HF3() != 0)) lisp_call(SERVICE_BREAK); else if ((cpu_HF2() != 0) && (cpu_HF3() != 0)) { lisp_call(READ_INPUT); return 1; } /* all of this paranoia is an attempt to deal with an apparent race condition where we jump in */ /* to look for both flags on, and see only one on */ return 0; } /* clservicebreak in next56.lisp -- HF3 used as signal for forced break */ /* if returned lisp value ever used, remember it is << 3 */ else { lisp_call(READ_INPUT); return 1; } } return 0; } int check_qp_HF3 (void) { int i; long lisp_call(int index); if ((qp_HF3() != 0) && (qp_HF3() != 0)) /* see note above */ { if ((qp_HF2() == 0) && (qp_HF2() == 0)) { i=0; while ((qp_HF3() != 0) && (qp_HF2() == 0) && (i<wait_time)) ++i; if ((qp_HF2() == 0) && (qp_HF3() != 0)) lisp_call(SERVICE_BREAK); else if ((qp_HF2() != 0) && (qp_HF3() != 0)) { lisp_call(READ_INPUT); return 1; } return 0; } else { lisp_call(READ_INPUT); return 1; } } return 0; } int checkHF3 (void) { int i; long lisp_call(int index); if ((HF3() != 0) && (HF3() != 0)) /* see note above */ { if ((HF2() == 0) && (HF2() == 0)) { i=0; while ((HF3() != 0) && (HF2() == 0) && (i<wait_time)) ++i; if ((HF2() == 0) && (HF3() != 0)) lisp_call(SERVICE_BREAK); else if ((HF2() != 0) && (HF3() != 0)) { lisp_call(READ_INPUT); return 1; } return 0; } else { lisp_call(READ_INPUT); return 1; } } return 0; } /* -------------------------------------- put and get ------------------------------------- */ #ifdef ARIEL_PC_56D inline void arielpc56d_putoneword(int word) { unsigned char hi = (word >> 16); unsigned char med = ((word >> 8) & 0xff); unsigned char low = (word & 0xff); dsp_putTX(current_active_dsp,hi,med,low); } inline void arielpc56d_getoneword(int *reply) { unsigned char hi,med,low; unsigned int ho; dsp_getRX(current_active_dsp,&hi,&med,&low); ho = hi; ho = (ho << 8) | med; ho = (ho << 8) | low; *reply = ho; } #endif inline int cpu_putoneword(int word) { #ifdef ARIEL_PC_56D arielpc56d_putoneword(word); #else if (CPU_ISR&2) put_cpu_tx(word); else { if (Await_cpu_TRDY(wait_time) != 0) lisp_call(AWAIT_PUT_SERVICE_BREAK); put_cpu_tx(word); } #endif return 0; } inline int qp_putoneword(int word) { if (QP_ISR&2) put_qp_tx(word); else { if (Await_qp_TRDY(wait_time) != 0) lisp_call(AWAIT_PUT_SERVICE_BREAK); put_qp_tx(word); } return 0; } inline int dspputoneword (int word) { int i; i = 0; if (current_active_dsp != -1) { if (current_active_dsp == 0) i = cpu_putoneword(word); else i = qp_putoneword(word); } return i; } inline int cpu_getoneword(void) { int reply; #ifdef ARIEL_PC_56D arielpc56d_getoneword(&reply); #else if (CPU_ISR&1) get_cpu_rx(&reply); else { if (Await_cpu_Data(wait_time) != 0) lisp_call(AWAIT_GET_SERVICE_BREAK); get_cpu_rx(&reply); } #endif return reply; } inline int qp_getoneword(void) { int reply; if (QP_ISR&1) get_qp_rx(&reply); else { if (Await_qp_Data(wait_time) != 0) lisp_call(AWAIT_GET_SERVICE_BREAK); get_qp_rx(&reply); } return reply; } inline int dspgetoneword(void) { int i; i = 0; if (current_active_dsp != -1) { if (current_active_dsp == 0) i = cpu_getoneword(); else i = qp_getoneword(); } return i; } inline int cpu_putarray(int beg, int end, int *arr) { #ifdef ARIEL_PC_56D dsp_putArray(current_active_dsp,arr+beg,end-beg+1); #else int *i,*last; last=arr+end; for (i=(arr+beg);i<=last;i++) { cpu_putoneword(*i); } #endif return (end-beg+1); } inline int qp_putarray(int beg, int end, int *arr) { int *i,*last; last=arr+end; for (i=(arr+beg);i<=last;i++) { qp_putoneword(*i); } return (end-beg+1); } inline int dspputarray(int beg, int end, int *arr) { int i; i = 0; if (current_active_dsp != -1) { if (current_active_dsp == 0) i = cpu_putarray(beg,end,arr); else i = qp_putarray(beg,end,arr); } return i; } inline int cpu_getarray(int beg, int end, int *arr) { #ifdef ARIEL_PC_56D dsp_getArray(current_active_dsp,arr+beg,end-beg+1); #else int *i,*last; last=arr+end; for (i=(arr+beg);i<=last;i++) { if (CPU_ISR&1) get_cpu_rx(i); else (*i)=cpu_getoneword(); } #endif return (end-beg+1); } inline int qp_getarray(int beg, int end, int *arr) { int *i,*last; last=arr+end; for (i=(arr+beg);i<=last;i++) { if (QP_ISR&1) get_qp_rx(i); else (*i)=qp_getoneword(); } return (end-beg+1); } inline int dspgetarray(int beg, int end, int *arr) { int i; i = 0; if (current_active_dsp != -1) { if (current_active_dsp == 0) i = cpu_getarray(beg,end,arr); else i = qp_getarray(beg,end,arr); } return i; } void clear_host_interfaces (void) { cpu_HI = NULL; qp_HI = NULL; } #ifdef ARIEL_PC_56D static void resetPC56d(void) { dsp_resetOn(current_active_dsp); /* usleep(10000); */ wait_a_while(10000); /* usleep in the past has caused lisp to hang -- will try it later */ /* 100000 ok */ dsp_resetOff(current_active_dsp); } #endif #define ARIEL_PC_IS_OPEN (-2) static port_t dev_port, owner_port, cmd_port; static int clm_dsp_error; int get_clm_dsp_error(void) {return clm_dsp_error;} int cpu_boot(int end, int *program) /* get Next built-in 56000, reset and load it */ { #ifdef ARIEL_PC_56D dsp_open(0); resetPC56d(); dsp_selectMemoryMap(current_active_dsp,1); dsp_fd = ARIEL_PC_IS_OPEN; cpu_putarray(0,end,program); #else int i,err; int *j,*pend; dev_port = 0; owner_port = 0; cmd_port = 0; err = SNDAcquire(SND_ACCESS_DSP, 10, 0, 0, NULL_NEGOTIATION_FUN, 0, &dev_port, &owner_port); if (err == 0) { err = snddriver_get_dsp_cmd_port(dev_port,owner_port,&cmd_port); if (err == 0) { err = snddriver_dsp_reset(cmd_port,SNDDRIVER_LOW_PRIORITY); } } clm_dsp_error = err; i=err; if (i != 0) return -2; cpu_HI = getDSPRegs(); /* get memory-mapped host interface */ if (cpu_HI == NULL) return -1; pend=program+end; for (j=program;j<=pend;j++) put_cpu_tx(*j); /* load program -- see lib56.lisp for the monitor code */ #endif put_cpu_icr(8); /* set HF0 to signal boot done -- see 56000 manual 10-43 */ return 0; } int cpu_close(void) { int err; #ifdef ARIEL_PC_56D if (dsp_fd == ARIEL_PC_IS_OPEN) dsp_close(current_active_dsp); dsp_fd = -1; return 0; #else if (cmd_port != 0) clm_dsp_error=port_deallocate(task_self(),cmd_port); /* the close code in DSPObject.c deallocates the command port before calling SNDRelease */ /* if we call it afterwards, port_deallocate returns 4 */ err=SNDRelease(SND_ACCESS_DSP,dev_port,owner_port); clm_dsp_error = ((clm_dsp_error << 16) | err); if (cpu_HI != NULL) free((char *)cpu_HI); else err = -2; cpu_HI = NULL; if (dsp_fd != -1) close(dsp_fd); else err = -3; dsp_fd = -1; return err; #endif } inline int checkhostInterface (void) { #ifdef ARIEL_PC_56D return (dsp_fd == ARIEL_PC_IS_OPEN) ? 0 : -1; #else if ((cpu_HI == NULL) && (qp_HI == NULL)) return -1; return 0; #endif } int hival(void) { int i; i = 0; if (current_active_dsp != -1) { if (current_active_dsp == 0) i = (int)cpu_HI; else i = (int)qp_HI; } return i; } inline int dspisopen (void) { #ifdef ARIEL_PC_56D return (dsp_fd == ARIEL_PC_IS_OPEN) ? 1 : 0; #else if (dsp_fd == -1) return(0); return(1); #endif } /* on chip, output results are collected in buffers to be flushed out when full. */ /* The HF2 bit is set when the dsp has filled its output buffers. We build a list */ /* at run time on the lisp side of the locations and sizes of these buffers, and */ /* here we read the contents. If needed, input data is also sent to the chip at */ /* this time. Then, the dsp sets out on its next buffer, while we merge the results */ /* into the respective files. Once that is finished, we return to lisp awaiting HF2 */ /* External delay lines change this scenario a bit. */ /* #define DATSIZ 32768 */ #define DATSIZ 131072 /* static int datbuf[DATSIZ]; */ /* dump dsp's "external memory" here (16K for QP) (32K for exp mem) (65536*2 for SFSU mem) */ /* If we ever take advantage of SFSU P mem for delay lines, change this to 65536*3 */ #ifdef ARIEL_PC_56D #define ZERO_SIZE 4096 static int *zero_buf; #endif static int *datbuf; static int data_ok = -1; check_datbuf (void) { int i; if (data_ok == -1) { datbuf = (int *)calloc((DATSIZ),sizeof(int)); #ifdef ARIEL_PC_56D zero_buf = (int *)calloc((ZERO_SIZE),sizeof(int)); for (i=0;i<ZERO_SIZE;i++) zero_buf[i]=0; #endif } data_ok = 0; } #define NO_IO -1 #define OUT_N 0 #define IN_N 1 #define EXT_DLY 2 /* RAN_IN_N = 3 and EXT_ZDLY = 4, but only used in debugging */ inn(int beg, int siz, int bufbeg, int *arr, int fsize) { /* file data in ARR starts at file sample BEG, file size is FSIZE, we want SIZ samples, and */ /* we are currently at BUFBEG within ARR */ int num,zeros,k; num = fsize-beg-bufbeg; /* max actual samples that could be read (can be negative) */ zeros = siz; /* in worst case (past eof), all samples are 0 */ if (num>0) /* if there are samples in arr (not past eof) */ { if (siz<num) k=siz; else k=num; if (current_active_dsp == 0) { cpu_putarray(bufbeg,bufbeg+k-1,arr); } else { qp_putarray(bufbeg,bufbeg+k-1,arr); } zeros = zeros - k; } if (zeros>0) { if (current_active_dsp == 0) { #ifdef ARIEL_PC_56D for (k=0;k<zeros;k+=ZERO_SIZE) { if ((zeros-k) < ZERO_SIZE) { num=zeros-k; num-=1; } else num=ZERO_SIZE-1; /* cc -O3 -DVOL=volatile -fwritable-strings -DARIEL_PC_56D -O -c -I. akkcl-c56.c -w */ /* if ((zeros-k) < ZERO_SIZE) num=zeros-k-1; else num=ZERO_SIZE-1; */ /* on the Pentium this compiles num=zeros+k+1 */ cpu_putarray(0,num,zero_buf); } #else for (k=0;k<zeros;k++) cpu_putoneword(0); #endif } else { for (k=0;k<zeros;k++) qp_putoneword(0); } } } inline outn (int outbeg, int outend, int *outa, int dspbeg, int *dspa) { int *i,*j,*last; last=outa+outend; if (outa != 0) { for (i=(outa+outbeg),j=(dspa+dspbeg);i<=last;i++,j++) { #ifdef ARIEL_PC_56D *i += *j; #else if ((*j) & 0x800000) *i += ((*j) | 0xffff0000); else *i += *j; #endif } } } /* outonebuf = dsp-merge-one-buffer and is used only in qplib56.lisp for partial DMEM flushes */ inline int cpu_outonebuf(int start, int stop, int *outloc) { int *i,*last, *first; int val; first=outloc+start; last=outloc+stop; for (i=first;i<=last;i++) { if (CPU_ISR&1) get_cpu_rx(&val); else val=cpu_getoneword(); if (val & 0x800000) *i += (val | 0xffff0000); else *i += val; } return 0; } inline int qp_outonebuf(int start, int stop, int *outloc) { int *i,*last, *first; int val; first=outloc+start; last=outloc+stop; for (i=first;i<=last;i++) { if (QP_ISR&1) get_qp_rx(&val); else val=qp_getoneword(); if (val & 0x800000) *i += (val | 0xffff0000); else *i += val; } return 0; } inline int outonebuf(int start, int stop, int *outloc) { int i; i = -1; if (current_active_dsp != -1) { if (current_active_dsp == 0) i = cpu_outonebuf(start,stop,outloc); else i = qp_outonebuf(start,stop,outloc); } return i; } inline dspsendinput(int *beg, int cursiz, int *sigops, int *sigptrs, int **sigadrs, int *sigsizes, int sigsiz) { int i; dspputoneword(cursiz); for (i=0;i<sigsiz;i++) { if (sigops[i] == IN_N) { inn(beg[i],cursiz,sigptrs[i],sigadrs[i],sigsizes[i]); sigptrs[i] += cursiz; } } } inline WaitForHF2_NotHF3 (void) { /* be real patient here -- make the wait time out pretty excessive */ int happy,i,waiting; happy = 1; waiting = 0; i = 0; while (happy) { i++; if (i>1000000) { put_CVR(0x96); while ((HF2() == 0) || (HF3() != 0)) { waiting++; if (waiting>2000) { lisp_call(AWAIT_OUTPUT_SERVICE_BREAK); } } } if (HF2() != 0) { if ((HF3() != 0) && (HF2() != 0)) { lisp_call(READ_INPUT); i = 0; } else if (HF3() == 0) { happy = 0; } } } } inline cpu_WaitForHF3_NotHF2 (void) { /* be real patient here -- make the wait time out pretty excessive */ int happy,i; happy = 1; i = 0; while (happy) { if (cpu_HF3() != 0) { if ((cpu_HF2() != 0) && (cpu_HF3() != 0)) { lisp_call(READ_INPUT); i = 0; } else if ((cpu_HF2() == 0) && (cpu_HF3() != 0)) { happy = 0; } } else { i++; if (i>1000000) lisp_call(AWAIT_GET_SERVICE_BREAK); } } } inline qp_WaitForHF3_NotHF2 (void) { /* be real patient here -- make the wait time out pretty excessive */ int happy,i; happy = 1; i = 0; while (happy) { if (qp_HF3() != 0) { if ((qp_HF3() != 0) && (qp_HF2() != 0)) { lisp_call(READ_INPUT); i = 0; } else if (qp_HF2() == 0) { happy = 0; } } i++; if (i>1000000) lisp_call(AWAIT_GET_SERVICE_BREAK); } } inline WaitForHF3_NotHF2 (void) { if (current_active_dsp == 0) cpu_WaitForHF3_NotHF2(); else qp_WaitForHF3_NotHF2(); } #define LOCSIZ 256 static int locs[LOCSIZ]; basicdspread (int beg, int end, int sigsiz, int dlys, int ins, int *sigops, int **sigadrs, int *sigptrs, int *sigbas, int *sigtop, int *sigsizes) { int i,k,curdsploc,num,cursiz,readsize; if (sigsiz>LOCSIZ) lisp_call(LOCSIZ_SERVICE_BREAK); check_datbuf(); if (dlys != 0) /* we have external delay lines in operation */ { for (i=beg;i<=end;i++) { for (k=0;k<sigsiz;k++) { if (sigops[k] == EXT_DLY) { int *pt,*sp; sp=sigptrs+k; pt=sigadrs[k]+(*sp); WaitForHF3_NotHF2(); dspputoneword(*pt); (*pt)=dspgetoneword(); (*sp)++; if ((*sp)>sigtop[k]) (*sp)=0; /* sigbas is index into *clm-delay-lines* */ } } } } curdsploc=0; cursiz=(end-beg); readsize=cursiz+1; WaitForHF2_NotHF3(); dspputoneword(readsize); for (i=0;i<sigsiz;i++) { if (sigops[i] == OUT_N) { locs[i] = curdsploc; num=dspgetarray(curdsploc,curdsploc+cursiz,datbuf); curdsploc += num; } } if (ins != 0) { dspsendinput(sigbas,readsize,sigops,sigptrs,sigadrs,sigsizes,sigsiz); } /* now the dsp should be running again -- merge current output into output buffers */ for (i=0;i<sigsiz;i++) { if (sigops[i] == OUT_N) { outn(beg,end,sigadrs[i],locs[i],datbuf); } } } rpc_dsp_merge_all_output(int beg, int end, int **sigadrs, int *sigops, int sigsiz, int *ldatbuf) { int cursiz,curloc,i; cursiz = (end-beg); curloc = 0; for (i=0;i<sigsiz;i++) { if (sigops[i] == OUT_N) { outn(beg,end,sigadrs[i],curloc,ldatbuf); curloc += cursiz; } } } #define RTS_op 12 #define Clear_HF3 698372 #define Move_X_HTX 585899 #define No_op 0 int dspstartagain(int tag, int tagloc) { return ( (checkhostInterface() == 0) && /* it appears that we have a pointer to its registers */ (HF3() != 0) && (HF3() != 0) && /* it appears to be sitting at our breakpoint handler */ (HF2() == 0) && (HF2() == 0) && /* (not bug56...) (on repeat reads see note under hf3) and */ (dspputoneword(Clear_HF3) != -1) && /* BCLR M-HF3 X-IO M-HCR... */ (dspputoneword(No_op) != -1) && /* NOP (2 wrd command in breakpoint handler)... */ (HF3() == 0) && /* executed ok! -- we must be at .break and */ (dspputoneword(Move_X_HTX) != -1) && /* MOVE X tag-loc X-IO M-HTX... */ (dspputoneword(tagloc) != -1) && /* (tag-loc)... */ (dspgetoneword() == tag) && /* tag is the same -- current instrument must already be loaded and */ (dspputoneword(RTS_op) != -1) && /* RTS (from .break)... */ (dspputoneword(No_op) != -1)); /* NOP (2nd word) -- we should now be awaiting the next note's data */ } /* Otherwise, reset chip and load everything */ int dspdataready (void) { int i; i = 0; if (checkhostInterface() == 0) i = checkHF3(); if (i == 1) return 0; return ( (checkhostInterface() == 0) && (HF2() != 0) && (HF2() != 0) && /* if we see .input's flags here by accident, endless trouble */ (HF3() == 0) && (HF3() == 0) && /* so read everything twice -- if only we had more of these flags... */ (HF2() != 0) && (HF3() == 0)); } int dspsetupprogram(int ix, int iy, int ex, int ey, int ep, int xoff, int yoff, int poff, int *ixarr, int *iyarr, int *earr) { if (dspputoneword(ix) != 0) return 1; if (ix != 0) { dspputoneword(0); if (dspputarray(0,ix-1,ixarr) != ix) return 2; } if (dspputoneword(iy) != 0) return 3; if (iy != 0) { dspputoneword(0); if (dspputarray(0,iy-1,iyarr) != iy) return 4; } if (dspputoneword(ex) != 0) return 5; if (ex != 0) { dspputoneword(xoff); if (dspputarray(0,ex-1,earr) != ex) return 6; } if (dspputoneword(ey) != 0) return 7; if (ey != 0) { dspputoneword(xoff); /* xoff because we're asking here for the chip's notion of the start of Y memory, not our own */ /* then yoff in the put array call because there we're dealing with our offset into external-memory */ if (dspputarray(yoff,yoff+ey-1,earr) != ey) return 8; } if (dspputoneword(ep) != 0) return 9; if (ep != 0) { dspputoneword(poff); if (dspputarray(poff,poff+ep-1,earr) != ep) return 10; } return 0; } set_active_dsp(int num) {current_active_dsp = num;} int get_active_dsp(void) {return current_active_dsp;} int set_wait_time (int ms) { int old_wait; old_wait = wait_time; wait_time = ms; return old_wait; } int get_wait_time (void) {return wait_time;}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.