DEC PDPs and Music/Sound Synthesis Summary ============================================================+ Revision 2b, December 2, 1995 _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_ When I began compiling this data, I was mostly interested in applications using DEC PDP-11s for music and sound synthesis, as I plan on experimenting with this when I get a chance to do so. However, information pertaining to various other types of PDPs began appearing, so I included that information as well. For me, at the present time, only information pertaining to PDP-8 and PDP-11 systems is practical - however, I find the information for other PDPs fascinating as well, and others may find it to be useful, so it's included. This is a summary of some of the information that I've collected after posting a message inquiring about DEC PDPs being used for music synthesis. Several very interesting postings to some newsgroups, unfortunately, got lost, and I wasn't able to include information from them in the original summary; however... after using gopher and veronica to do a bit of searching, I found some of the "lost" postings and have included information from them in this summary. If you posted a reply, or sent me e-mail, and don't see information from your reply in this summary, please contact me with the information and I will include it. If anyone else has saved any postings from which information didn't get included, please send them to me and I'll include them in this summary. Although this summary primarily pertains to PDP-11s, there is also some information pertaining to PDP-7s, PDP-8s, PDP-10s and PDP-15s. Admittedly, this summary isn't very well organized; I suppose that's because I'm possibly not all that well organized. :-) Hopefully the format of this summary is somewhat useful - I wasn't exactly sure how to organize it, so this is what resulted. Most of the information in this summary is not in any sort of order... however, I did attempt to put some information pertaining to PDP-6s, PDP-7s, PDP-8s and PDP-10s in order. Most of what's here is organized as follows: just the way that things happened to fall into place while I was sorting through various bits of information. Thanks very much to those who responded to my postings about using PDPs for music/sound synthesis! Hopefully this summary will help to provide those interested in using their PDPs for music/sound synthesis with some very useful and fascinating information. If anyone has any information pertaining to synthesis equipment using tubes, or valves, I'd also be most interested in that information. One place where you can obtain a copy of this summary is from my web pages, http://www.access.digex.net/~rdd in the area under the directories: pdp, pdp-11 and then Synth_and_MIDI, in the filename pdp-synth.summary.rev2.gz. It can also be FTP'd from ftp.digex.net at /pub/access/rdd/pdp/pdp-11/Synth_and_MIDI/pdp-synth.summary.rev2.gz. Note that I've placed quite a few other MIDI and music synthesizer related files in the archive mentioned above as well, for help if anyone is interested in working on a PDP-11 based MIDI system or music synthesizer. Although there is MIDI information here, my main interest with all this is analog (I don't even own any CDs, and am in no hurry to own any) music synthesis, and control of analog music synthesis equipment through computers in possible conjunction with a MIDI interface. One non-PDP related note: another system that I plan on using along with DEC PDP-11s and an 8s is a PERQ graphics workstation. Is there anyone reading this who is familiar with using a PERQ for any sort of music or sound synthesis using external or internal circuitry? I was considering using the PERQ as a graphics front-end to PDP-11 and PDP-8 controlled music synthesis equipment. Some may say that this is a sign of madness, which I won't dispute. As I receive new information, I'll hopefully update this summary every so often... possibly. Thanks to Dieter Dworkin Muller (dworkin@village.org), copies of this summary can also be FTP'd from: ftp.village.org in /pub/pdp-11/pdp11.music[.gz]. R. D. Davis -------------------------------------------------------------------------- Table of Contents ----------------- 0) Original posting reqesting information 1) Digital Domain at Stanford, a PDP-6 and Foonley PDP-10 emulation 2) Music on PDP-7s 3) Music on PDP-8s 4) Institut de Recherche et Coordination Acoustique/Musique and PDP-10/11 5) Music 11 at MIT 6) Northwestern 7) Sawdust - University of Illinois 8) EMS in Stockholm 9) P850 User Group Music Program 10) UCSD 11a) 11/34 at Princeton 11b) 11/44 at Princeton 12) Q-Bus Music Board and Synclavier 13) Michael Hyman's music synthesis software 14) The Grateful Dead and PDP-11 music synthesis 15) MIDI Interface to PDP-11 16) More PDP-11 Synthesizer HW and SW Information 17a) Computer Music Languages, part I 17b) Computer Music Languages, part II 18) Groupe de Recherches Musicales -------------------------------------------------------------------------- 0) Posting reqesting information -------------------------------- Contributor: RDD "Is anyone here using a DEC PDP-11 to control any music synthesis equipment? I've heard that some people have used these systems for this, but I was wondering how many were still doing this... it seems like this could be a good use for my PDP-11s. :-)" "I've also heard that the Grateful Dead used a PDP-11 for music synthesis (gee, I guess that means that PDP-11s can be classified as portable computers! :-). Can anyone provide any information or details about the setup that they used?" "If you've used a PDP-11 for music synthesis, how did you connect it to the other music synthesis equipment: serial ports, special boards? What operating system did you use? Is the software used available anywhere for anonymous FTP?" "One other semi-related question, does anyone know of any PERQ graphics workstations being used for music synthesis?" -------------------------------------------------------------------------- 1) Digital Domain at Stanford, a PDP-6 and Foonley PDP-10 emulation ------------------------------------------------------------------- Contributors: Peter Cassidy, peterc@dub.comm.mot.com Andrew Clegg, abc@warpfive.demon.co.uk Bill Schottstaedt, bil@ccrma.Stanford.EDU Lon Stowell, lstowell@pyrnova.mis.pyramid.com "After posting about the Stanford folks doing digital music [Digital Domain], I have committed the unpardonable sin of RTFM." [LS] "It seems that Stanfords CCRMA, as of 1983, did NOT have a PDP of whatever variety." [LS] "What they had was a Foonly F2 "emulating a DEC PDP-10"." [LS] "What? Foonly? Now THAT sounds like a sufficiently oddball name that there is probably a boring story behind it." [LS] > What? Foonly? Now THAT sounds like a sufficiently oddball > name that there is probably a boring story behind it. "Of course there is -- it has about 2/3s of a page in the New Hacker's Dictionary." [AC] "It was a successor to the PDP-10 that was built at SAIL and was largely forgotten due to a late arrival in the market." [AC] "Interesting trivia: *Its* successor the Super Foonly F-1 (note: not *a* Super Foonly F-1, there was only one) did the graphics in Tron." [AC] "Not to mention the fact that the great Wendy Carlos did the soundtrack!!" [PC - regarding the above quote] "If I remember right we still had the PDP-6 at that time -- it eventually went to a DEC museum. The Foonly F4 was in the building, but wasn't running the OS we wanted until 1984. David Poole designed and built the Foonlys -- basically a poor-man's PDP-10 -- and there was indeed a suitably dull story about the name." [BS] "We talked a lot about using PDP-11's, mainly to be compatible with UCSD, but never got around to doing anything." [BS] -------------------------------------------------------------------------- 2) Music on PDP-7s ------------------ Contributor: John Fitch, jpff@maths.bath.ac.uk "When I was a graduate student one of my contemporaries used a detuned radio and a PDP7 to play 3 part Bach partitas. He coulkd not manage 4 part as it broke up. The really cool thing was that as the PDP7 had 4 gears and an accelerator (variable clock speed if you prefer) one could get fine tuning after it was playing. It was part of his dissertation; I cannot remember his name at present, but he was Syrian and last time I saw him he was post-doc and working for Thomas J Watson Research Center, IBM, in Yorktown Heights. The project would have been in early 1968." -------------------------------------------------------------------------- 3) Music on PDP-8s ------------------ Contributors: John Boyes, em09@liverpool.ac.uk Tony Duell, ard@p850ug1.demon.co.uk Mike McCrohan, McCrohan@iol.ie Paul Rabin, rabin@osf.org Bob Schor, bschor@vms.cis.pitt.edu Karlo Takki, ktakki@delphi.com "I do remember someone writing some code to play music on a PDP8. You had to hold an un-tuned transistor radio close to it to hear the music. Hows that for a radio interface? :-)" [JB] "In Digital in Galway around 1975, John Lewis, manager of the training department, hooked the link bit of a PDP-8/e to an amplifier and had it produce music. Initial attempts produced pure tones that, though interesting, were not too pleasant to listen to. Later he managed to incorporate subharmonics, if that's the correct term, to give the notes a more natural sound. He produced a 45rpm record of Irish music by this method, which was distributed with one of Digitals in house magazines. All through the link bit." [MM] "And the Linc-8 had a volume control knob that "listened" to (I think it was) the least-significant bit on the Linc accumulator (this was circa 1967). I coded the "Ode to Joy" on this sucker ..." [BS] "Here's one more item for your list. Around 1968 I programmed a LINC-8 computer at the University of Pennsylvania Medical School to play the Symphonia from Bach's Cantata #29. Although the synthesis technique was monophonic, in passages of rapid alternation of repeated notes there was an illusion of polyphony. Of course, this was inspired by the then just-released Switched-On Bach record." [PR] "Hey... There's a PDP8/e on my desk at the moment. Maybe I should fire here up (not literally - it's RK05's that emit flames :-)), and try and do something like this. I'm sure porting the P850 User Group program I mentioned in another posting would be possible - if it runs on P850's, PDP11's, Intel 8080, and 6809's, I'm sure it can run on an '8" [ARD] "I'm sure my musical knowledge (what knowledge???) is no way up to producing anything interesting sound-wise, but it could be fun to try." [ARD] - "Thanks for posting the thread about DEC PDP-* and music synthesis... very entertaining reading . It also reminded me of an album I had bought over twenty years ago that features a track recorded with a PDP-8. The album is _Phantasmagoria_ (Warner Bros. BS-2628), recorded in 1972 by a British group called Curved Air. The second track on side two is entitled "Whose Shoulder Are You Looking Over Anyway?". From the liner notes: "Recorded at E.M.S. (London) by kind permission of Peter Zinovieff. This track consists entirely of tapes of Sonja's voice analysed and processed by a PDP 8/L computer and a Synthi ^^^^^^^ 100 synthesizer. The final tapes were edited and prepared for performance by Francis Monkman and Robert Carvell." Sonja Kristina, the band's vocalist, recites a fragment of poetry ("When I was a little ghost/a merry time had we...) which, after processing, sounds like it's been "vocoded". As I recall, the Synthi 100 was a large synth constructed by E.M.S. (makers of the suitcase-sized VCS3 used by Pink Floyd on the _Dark Side..._ LP, as well as Curved Air on their previous release _Air Conditioning_). The Synthi 100 was such a big beast, one wonders what they needed a PDP 8 for . It still sounds pretty strange, even after 23 years. I was 12 when I bought the album; what sounds like randomness had me spellbound back then. Now, I think I could get the same effect with a couple of ring-modulators (hahahaha). One caution: I haven't verified that the PDP 8/L in question is the DEC product referred to in the original posts. But I'm pretty certain that it is." [KT] -------------------------------------------------------------------------- 4) Institut de Recherche et Coordination Acoustique/Musique and PDP-10/11 -------------------------------------------------------------------------- Contributor: Stephane TSACAS, slt@amertume.ufr-info-p7.ibp.fr "Maybe you can ask someone from the IRCAM, Institut de Recherche et Coordination Acoustique/Musique (Paris), I think they had a pdp10 the Vaxen, so I'm quite sure they had pdp11 some too. Try : http://www.ircam.fr/ ." -------------------------------------------------------------------------- 5) Music 11 at MIT ------------------ Contributors: Josef Jurek, jaj3@midway.uchicago.edu Joerg Spix, Joerg.Spix@arbi.informatik.uni-oldenburg.de -"Barry Vercoe and others at MIT in the late 70s used a PDP11 to compute sound using a program called Music 11, which was the pre-cursor of Csound. A PDP11 was also used at Northwestern to compute sound in the early 80s, though I do not know what program(s) they were using. At both of these institutions, sound was computed directly on to the hard disk, and not in real time." [JJ] - "Csound is still available from MIT (at no cost). You can probably find their address in the comp.music FAQ." [JJ] - Although not directly relevent to this summary, Csound was ported to Linux by Benjamin Ketcham (bketcham@u.washington.edu). - There possibly existed a version of Music 4 or Music 5 for the PDP-11, which had become Music 11. For further information about Music 4 or Music 5, try contacting Barry Vercoe from the MIT Media Labs. Also, the book _The Technolology of Computer Music_ by Max V. Matthews, published by MIT Press between 1960 and 1970, may provide further information. [JS] - "It's not the incredible sound machine, I think an Atari ST doesn't run much slower... Be prepared to wait some days for your output and have tape streamer to record the soundfiles. Then convert the soundfiles to analog voltages with a 12-, 14-, or 16-bit DA-converter." [JS] - Music 11 evolved from Music 360 (for the IBM 360 - Vercoe, MIT), which evolved from Music 4B (what system? - Winham/Howe, Princeton), which evolved from Music 4 (what system? - Max Mathews, Bell Labs). Music 5 evolved from Music 4, but is not a predecessor of Music 11, etc. -------------------------------------------------------------------------- 6) Northwestern --------------- Contributors: Robert Bristow-Johnson, robert@audioheads.win.net Josef Jurek, jaj3@midway.uchicago.edu - Used a PDP-11 to compute sound in the early 1980s - As with Music 11, "...sound was computed directly on to the hard disk, and not in real time." - "I was at Northwestern at the time they moved from PDP-11 to a Pyramid RISC super-mini (approx. 1981-85). They DID have a simple real-time synthesizer on their PDP-11 and I modified the program to do simple nonlinear wave-shaping synthesis for 4 voices real-time. They had some special wavetable hardware of their own design and also used the DR11-B and DR11-C boards. I imagine Gary Kendall is still there, you should find out directly from him." [RB-J] -------------------------------------------------------------------------- 7) Sawdust - University of Illinois ----------------------------------- Contributor: Josef Jurek, jaj3@midway.uchicago.edu - "Herbert Brun at the University of Illinois in the 70s used a PDP11 to run his Sawdust program, a program which does both synthesis and computer-assisted composition." -------------------------------------------------------------------------- 8) EMS in Stockholm ------------------------------------- Contributors: Robert J. Dow, rjd@festival.ed.ac.uk Keith Kothman, kkothman@weber.ucsd.edu - Used a PDP-11 for music syntheses and "may still be doing so". [KK] - "They had a special hardware interface (major Star Trek looking thing), and used the PDP-11 to control a bank of digital oscillators in real time." [KK] - "EMS in Stockholm used their PDP to control a large bank of (homemade) analogue synthsis gear, although this system has been shut down for some years now (I think they still have the machine, etc.). This allowed them to control the sythesis in realtime." [RJD] - To contact EMS, write to: " Institute for Electroacoustic Music in Sweden Soder Malarstrand 61 (both the o and the first a have .. over) 117 25 STOCKHOLM Sweden "[KK] -------------------------------------------------------------------------- 9) P850 User Group Music Program -------------------------------- Contributor: Tony Duell, ard@p850ug1.demon.co.uk "Does the (imfamous ?) P850 User Group music program count? It was first written for a Philips P850, and then ported to a PDP11/45 (the CPU speed is important), and an Intellec 8I." "This program reads 2 bytes from paper tape, and treats them as the pitch and #cycles of a note. It then uses a pair of nested loops to toggle a bit of a parallel output port the correct number of times, before going back for another pair of bytes. It finally halts when it reads a 0 from the tape. You link a loudspeaker through a 1-transistor circuit to the output port." "One unintended feature was the fact that the clicking of the paper tape solenoid (on a Trend reader) gives an acompanyment to the music..." "I probably have the source arround here somewhere (on paper tape!). I should dig it out and post it. I should also port it to PERQ microcode, and link a trend reader amd the loadspeaker box to the PERQlink port." [ARD] Yes, please do port it to PERQ Microcode! Better yet, let's set up a link between a PDP-11 and the PERQ and use the PERQ to display anything requiring graphics for it. :-) [RDD] -------------------------------------------------------------------------- 10) UCSD -------- Contributor: Romain Kang, romain@sword.eng.pyramid.com "In jaj3@quads.uchicago.edu (josef jurek) writes about computer music labs that used PDP-11's. I also recall UCSD had a few PDP-11's around, according to a technical paper that described their facilities and applications. I believe their main cruncher was a PDP-11/55 with lots o' fast bipolar memory (lots for an '11, anyhow)." -------------------------------------------------------------------------- 11a) 11/34 at Princeton ---------------------- Contributors: Tony Duell, ard@p850ug1.demon.co.uk Romain Kang, romain@sword.eng.pyramid.com "Princeton had a PDP-11/34 (I was its resident UNIX hack) but it was mainly used as a AD/DA platform, using a DR-11W interface to custom made convertors. The main compute engine was the campus mainframe (a 3033, then a 3081), and we carried tapes from the computer center over to the music lab to hear our latest creations. We had a special user-space filesystem because the V7-style filesystems couldn't handle the throughput, and we *still* had to turn off clock interrupts to get clean conversions. On the other hand, we could tell how much the convertors had been used by checking how far behind the time of day clock had fallen..." [RK] > Princeton had a PDP-11/34 (I was its resident UNIX hack) but it was > mainly used as a AD/DA platform, using a DR-11W interface to custom > made convertors. The main compute engine was the campus mainframe "I've often thought about making a DMA-interfaced DAC board, either as an OIO board for a PERQ (using the 2nd ethernet DMA channel), or as a UNIBUS card. I suppose I could use a DR11-W or -B for part of it..." [ARD] "Of course, the small PDP-11's weren't cost effective compute engines once the MicroVAX II came out around 1985. The main reason people kept them tended to be for I/O capability, which was hard to get on those tiny Q-BUS machines. Today, a $1500 multimedia PC is capable of just about anything the old $50k 11/34 system could handle, and then lots more CPU cycles to boot." [RK] > Of course, the small PDP-11's weren't cost effective compute engines > once the MicroVAX II came out around 1985. The main reason people kept > them tended to be for I/O capability, which was hard to get on those > tiny Q-BUS machines. Today, a $1500 multimedia PC is capable of just > about anything the old $50k 11/34 system could handle, and then lots > more CPU cycles to boot. "just about anything... except for reliability (I've had to fix many more problems on a single PC than all my PDP's put together), maintainability (board swapping is not how you repair anything - that's done with a 'scope, a logic probe/analyser, and a box of chips), documention (give me a real printset any day), etc...." [ARD] "I'd like to see the PC with 8 (demountable) hard drives, SCSI, ST506, 32 serial ports, DMA I/O, vector graphics, graphics coprocessor, A/D, D/A, and all the other options you can (easily) put on a single PDP-11" [ARD] -------------------------------------------------------------------------- 11b) 11/44 at Princeton ----------------------- Contributor: Jonathan Baker, baker@sacco.nyu.edu >In article <3gtln1$p30@umbc8.umbc.edu> rdavis4@umbc.edu "R. D. Davis" writes: >> Is anyone here using a DEC PDP-11 to control any music synthesis >> equipment? I've heard that some people have used these systems for >> this, but I was wondering how many were still doing this... it seems >> like this could be a good use for my PDP-11s. :-) "When I was at Princeton in the mid-80's, we used a PDP-11/44 running Berkeley Unix 2.9 to control music synthesis equipment. Actually, we had a two-phase system. One would write a program using the music synthesis language on the IBM mainframe, and run it as a batch job on MVS. This would produce a big dataset of digitized sound. One would then copy this to a tape, carry the tape from the computer center to the engineering building, go down to the basement, load the tape onto the PDP-11, and run the D-to-A conversion program, producing a cassette tape of one's music. This system was scrapped in about 1987, when the music department switched to MicroVax II's running Ultrix to do the entire synthesis job (a MicroVax II is about the equivalent of a VAX 750, which was a reasonably powerful mini - it could support 24 users many of whom were running the VLSI design software). You might contact Professor Paul Lansky (Music) and/or Professor Kenneth Stieglitz (Computer Science) at Princeton for information about their music synthesis programs. Write care of their respective departments, Princeton University, Princeton NJ 08544."[JB] -------------------------------------------------------------------------- 12) Q-Bus Music Board and Synclavier ------------------------------------ Contributors: Paul Repacholi, prep@yarrow.wt.uwa.edu.au Billy Y., billy@mix.com > And the M-???? that was part of the Micro-Power Pascal kit. > Anyone got one? [PR] "Perhaps this is the EY-0105E-MS-0101 Q Bus Music Board? I have one of these, but I've never fired it up. Kind of primative by today's standards, but interesting if only because DEC made it." [BY] "I also think the Synclavier was, at least at one time, PDP-11 based?" [BY] -------------------------------------------------------------------------- 13) Michael Hyman's music synthesis software -------------------------------------------- Contributor: Michael Hyman, mikeh@netaxs.com "Don't know if this counts, but in the 70's I programmed a PDP-11/34 to play synthesized music (monophonic) in real-time through a DAC port. The software was written in FORTRAN and controlled frequencies and note timings with DO loops! It was fun and interesting at the time (Oh to be young!), but I can't imagine why anyone would want to make music this way in 1995." -------------------------------------------------------------------------- 14) The Grateful Dead and PDP-11 music synthesis ------------------------------------------------ Contributors: Joshua Edward Barnes, barnes@galileo.IFA.Hawaii.Edu Don Nichols, dnichols@d-and-d.com Someone [DN] told me that someone told him that the Grateful Dead used a PDP-11 controlled synthesizer before MIDIs were used. Can anyone provide some details about the setup that they used? For example, what type of PDP-11 was used, what type of synthesis hardware was used, what type of software was used, what was the timeframe in which it was used, etc. Someone else heard rumours about this: "I've heard rumors about early computer-based music synthesis at Dead shows, ca. 1974. I believe this was a collaboration between Phil Lesh and Ned Lagin. Apparently it was not well received in live performances. An album called _Seastones_ by Lagin, Lesh, and a bunch of the other usual suspects was released in '75 -- you might (or might not) find more info there. I've never heard it, myself, so I don't really know." [JEB] -------------------------------------------------------------------------- 15) MIDI Interface to PDP-11 ---------------------------- Contributors: Andy Stewart, stewart_andy@decus.org.au Gary ?, gary@minster.york.ac.uk John Wilson, wilsonj@alum01.its.rpi.edu "Minor problems, the news reader suddenly won't let me Answer the posting." [AS] "To Whom ever asked about PDP-11s and Music," [AS] "I know a friend of a friend whom I think connected his MIDI synthesizer to his PDP-11/23. I think he also added ROMS to his VT100 so it used Double Height characters to display music notation." [AS] "I'm sure he is on the net but I don't know his Email address. Mail me If you would like to communicate with him." [AS] "I used an 11/23 for music a few years ago. I built a MIDI interface to connect to a dlv11 (is that the correct number? the four port serial card) and would boot the 11/23 from one of my other 23s running v7. (The boot was neat, it used console odt to load a bootstrap in octal, and then run to load the next stage, etc - didn't need any boot roms!) I also wrote a stand-alone real-time kernel to handle all the midi stuff. Sadly I haven't touched this stuff in years. I got fed up waiting for the l o n g compilation times on my 23. I've been trying to get support for 11s on my linux box. I think there is a now a gcc backend. Has anyone managed to get a cross development environment for linux going. Alternatively, does anyone know of cross development tools which will run on a VAXstation under ULTRIX? cheers... gary PS The v7 11/23 was bought from our muic department and it still has the rt11 version of csound, or was it cmusic, on it." [G?] * * * The following MIDI interface info. was ftp'd from John Wilson's FTP archive: README: ------ This directory contains information relating to MIDI on PDP-11s. dlmidi.txt Schematic of MIDI adapter for DL11 ports. midi.mac DL11 MIDI driver and demo. thmfit.mac Very incomplete program that was eventually supposed to fit a second voice against a given theme, obeying the rules of Palestrinian counterpoint. It has a long way to go, I was just proud of myself for managing to incorporate PDP-11 hacking and trivial hardware design into a senior project for a B.A. in Music at a liberal arts college. Even *they* couldn't stop me from being a geek! Anyway this program can optionally play its output on the synth. dlmidi.txt: ---------- DL11 MIDI interface. Designed and prototyped by John Wilson, Bennington College, 1991. [note: I made a few very slight changes, such as adding a few missing pin numbers and replacing tabs with spaces. - R.D.D.] Vcc (+5VDC) ^ | +--- 2.2 K ------------+ | | | / C -+-- 470 ohms ------ 2N2907 TTL TxD H B \ E | +------- 220 ohms -----> +------- 220 ohms -----> | = gnd Vcc ^ +-------------------+ | | o 13 1 K +-------+ 12 | 6 +-------+ 2 TTL RxD L (note)| S D|---------------+-------|\ +-|--+--- 220 ohms --> ----------------|Q | | | = V | ^ 1N914 8 | R CK|-- 1 MHz osc. (8) +---|/ +-|--+---------------> +-------+ 11 | 5 +-------+ 3 o 10 = 6N138 | Vcc gnd +---^ 1/2 7474 note: this flip-flop is being used as an inverter just so we don't have to add another chip. the clock is 32x the baud rate, which is 2x faster than the UART samples so we can safely neglect the distortion of the input signal. Vcc ^ | o 1 EXT CLK 5 +---+---+ 2 +-------+ ----------------|Q R D|---+ | 1 MHz | | | | | xtal | +---|Q S CK|---)---| osc. | | 6 +---+--+ 3 | 8 +-------+ | o 4 | +-------)-------+ | +---> Vcc 1/2 7474 Vcc: (with .1 uF to ground) 7474 pin 14 crystal osc. pin 14 6N138 optoisolator pin 8 gnd: 7474 pin 7 crystal osc. pin 7 6N138 pin 5 (as shown above) midi.mac: -------- ;++ ; ; Test program for the MIDI port. ; ; By John Wilson. ; ; 11/11/90 JMBW Created. ; 05/13/91 JMBW MIDI input actually works now. ; ;-- .mcall .gtlin,.inten,.print,.ttyout ; .device=emt+375 ; rcsr= 175610 rbuf= 175612 xcsr= 175614 xbuf= 175616 vec= 300 vec=310 ; comma= ', ; start: ; prepare to crash mov #jam,r0 ;area .device ;disable ints on ^C ; set up receive vector mov #rxisr,@#vec ;addr mov #340,@#vec+2 ; mov #100,@#rcsr ;enable ints tst @#rbuf ;clear junk .print #clear ; .rem _ 1$: call get ;get a char cmp r0,#376 beq 1$ mov r0,r1 ash #-6,r0 bis #'0,r0 .ttyout mov r1,r0 ash #-3,r0 bic #^C7,r0 bis #'0,r0 .ttyout mov r1,r0 bic #^C7,r0 bis #'0,r0 .ttyout .ttyout #15 .ttyout #12 br 1$ .rem _ ; _ loop: ; main loop call get ;get a char 10$: cmp r0,#220 ;key-down? bne loop mov r0,r5 ;save call get ;get key # 20$: mov r0,r1 call get ;get velocity tst r0 ;0? beq 60$ ;key-up 30$: sub #36.-1,r1 ;convert valid keys to 1-49. bcs loop ;never mind cmp r1,#49. ;valid? bhi loop mov #ebuf,r4 ;pt at end of buf mov #'#,r0 ;char cmp r5,#220 ;key-down? beq 40$ ;yes mov #' ,r0 ;key-up 40$: movb r0,-(r4) ;last char movb #'H,-(r4) ;DCA command 50$: clr r0 ;sxt div #10.,r0 ;divide bis #'0,r1 ;cvt movb r1,-(r4) ;save mov r0,r1 ;copy bne 50$ ;loop movb #';,-(r4) ;[; movb #'[,-(r4) movb #33,-(r4) .print r4 call get ;get next mov #220,r5 ;; (OK?) tstb r0 ;cmd or data? bpl 20$ ;data, use same command br 10$ ;cmd, start over 60$: clr r5 ;key-up br 30$ ;continue ;+ ; ; Get a char. ; ;- get: tst len ;anything? beq get ;loop if not clr r0 ;get empty ptr bisb empty,r0 movb ring(r0),r0 ;get char incb empty ;bump ptr dec len ;count char bic #^C377,r0 ;isolate low 8. rts pc ;+ ; ; Handle receive interrupts. ; ;- rxisr: .inten 4 ;;drop to PR4 10$: movb @#rbuf,r4 ;get char cmp r4,#376 ;heartbeat? beq 20$ ;don't waste buffer space tstb len+1 ;will it fit? bne 40$ ;no clr r5 ;get ring offset bisb fill,r5 movb r4,ring(r5) ;save char incb fill inc len ;count it 20$: ; poll for more tstb @#rcsr ;more? bmi 10$ ;yes rts pc 30$: ; just lose if the queue is full tst @#rbuf ;flush 40$: tstb @#rcsr ;more? bmi 30$ ;yes, flush it rts pc ; clear: .ascii <33>//[H/<33>/[J/<200> .even ; jam: .byte 0,14 ;.DEVICE, non-linking .word .+2 .word rcsr,0 ;0 => RCSR .word 0,0 ; .blkb 7 ;[;nnHc ebuf: .byte 15,200 ;end of string .even ; ring: .blkb 400 fill: .byte 0 empty: .byte 0 len: .word 0 ; .end start thmfit.mac: ---------- .title theme fit .enabl lc ;++ ; ; Program to fit a theme against itself. ; ; By John Wilson. ; ; 10/12/90 JMBW Created. ; 11/09/90 JMBW Random melody code. ; 11/11/90 JMBW Play over MIDI port. ; 12/07/90 JMBW Cares about key signature now. ; ;-- .mcall .exit,.gtlin,.print,.rsum,.spnd,.ttyout .gtim= emt+375 .mrkt= emt+375 ; ; MIDI port locations (DL11 w/MIDI board) midcsr= 175610 ;control/status register midvec= 300 ;interrupt vector ; numhis= 5 ;# of high scores to save ; tab= 11 lf= 12 cr= 15 ; .asect ; ; high score list entry: .= 0 score: .blkw ;score for this string numnot: .blkw ;# of notes in string notstr: .blkw ;note string scrlen= . ;length of score entry ; ; define intervals (in semitones): .= 0 unison: .blkb ;unison min2: .blkb ;minor second maj2: .blkb ;major second min3: .blkb ;minor third maj3: .blkb ;major third perf4: .blkb ;perfect 4th trtone: .blkb ;tritone perf5: .blkb ;perfect 5th min6: .blkb ;minor 6th maj6: .blkb ;major 6th min7: .blkb ;minor 7th maj7: .blkb ;major 7th oct: .blkb ;octave ; ; note durations: breve= 200 ;breve (double whole) sbreve= 100 ;semi-breve (whole) minim= 40 ;minim (half) crtcht= 20 ;crotchet (quarter) quaver= 10 ;quaver (eighth) sqvr= 4 ;semi-quaver (sixteenth) dsqvr= 2 ;demi-semi-quaver (thirty-second) ; ; chords we know (ignore inversions): .macro ch name,mask b'name= ^B'mask ch'name=foo foo= foo+1 .endm foo= 1 ; ch dim, 000001001001 ;diminished triad ch dim7,001001001001 ;diminished 7th ch min, 000010001001 ;minor triad ch min7,010010001001 ;minor 7th ch maj, 000010010001 ;major triad ch dom7,010010010001 ;dominant 7th ch maj7,100010010001 ;major 7th ch min6,000100100001 ;minor 6th ch maj6,001000100001 ;major 6th ; sw6= &^C ;convert chmin6 to chmaj6 & v.v. ; ; notes are stored as follows: .= 0 value: .blkb ;note value (standard MIDI values) duratn: .blkb ;duration (half, quarter, etc.) prev: .blkw ;previous note in line next: .blkw ;next note in line chprev: .blkw ;prev note in chord chnext: .blkw ;next note in chord flags: .blkw ;flags cont= 100000 ;note is continued in next chord length= . ;length of a note record ; ; MIDI octaves .= 0 oct0: .blkb 12. oct1: .blkb 12. oct2: .blkb 12. oct3: .blkb 12. oct4: .blkb 12. oct5: .blkb 12. ;oct5+c is middle C oct6: .blkb 12. oct7: .blkb 12. oct8: .blkb 12. oct9: .blkb 12. oct10: .blkb 8. ; ; offsets of each note into the octave ($ means #) .= 0 c: .blkb c$: .blkb d: .blkb d$: .blkb e: .blkb f: .blkb f$: .blkb g: .blkb g$: .blkb a: .blkb a$: .blkb b: .blkb ; ; MIDI port regs rcsr= midcsr ;rcvr csr ; b7=rdy ;char is ready ; b6=ie ;interrupt enable rbuf= midcsr+2 ;rcvr buf ; b15=err ;error bit, one of the following: ; b14=or ;overrun error (not read in time) ; b13=fer ;framing error (stop bit was not 1) ; b12=per ;parity error xcsr= midcsr+4 ;xmtr csr ; b7=rdy ;rdy to xmit ; b6=ie ;interrupt enable ; b1=maint ;maintenance mode ; b0=break ;continuous break (may be jumpered out) xbuf= midcsr+6 ;xmtr buf .= midvec rvec: .blkw 2 ;rcvr vector xvec: .blkw 2 ;xmtr vector ; .macro retblk reg mov freblk,(reg) mov reg,freblk .endm ; .sbttl beginning of code ; .psect reent: nop ;re-entry addr is s.a. -2 start: ; set up free block list mov #blocks,r5 ;pt at them mov #blklen/length-1,r3 ;length of area clr (r5) ;first one is end of list 10$: mov r5,r4 ;copy add #length,r4 ;skip to next mov r5,(r4) ;link it mov r4,r5 ;skip sob r3,10$ ;loop mov r5,freblk ;head of list ; init random #'s mov #gtim,r0 ;get time .gtim ;for randomness ; .print #hello aa: ; test random string routine call clrscr ;clear scoreboard call notein mov r0,r5 ;copy mov r0,(pc)+ ;save 10$: .word ; string is at (r5) ; find length mov r5,r4 ;copy clr r3 ;zap 20$: inc r3 ;count mov next(r4),r4 ;link bne 20$ ;loop mov r3,-(sp) ;save length mov #500.,r2 ;loop count 30$: mov r2,-(sp) ;save ; get notes to match mov 2(sp),r0 ;length clr r1 ;below our voice call rndnot ;gets random string mov 2(sp),r0 ;length call chekhi ;check high score mov (sp)+,r2 ;restore count sob r2,30$ ;loop ; print high score list mov #hiscor,r4 ;pt at high score list mov #numhis,r3 ;length 40$: mov r3,-(sp) ;save ; clean the original theme mov 10$,r0 ;get ptr 50$: clr chnext(r0) ;zap mov next(r0),r0 ;link bne 50$ ;loop ; display score and string mov score(r4),r1 ;score call prnum .ttyout #tab mov notstr(r4),r5 ;point mov r4,-(sp) ;save call dispst ;display mov (sp)+,r4 ; input .gtlin #kbbuf,#playit ;ask whether to play it cmpb kbbuf,#'N ;don't play it? beq 60$ ;right ; play it - link to theme mov r4,-(sp) ;save mov 10$,r5 ;top mov notstr(r4),r4 ;bottom call link ;link it call play ;play mov (sp)+,r4 60$: add #scrlen,r4 ;skip mov (sp)+,r3 sob r3,40$ ;loop br aa playit: .ascii /Play? /<200> .even ; bb: .rem _ ; display the results 40$: mov (r0)+,r2 ;get parms mov r0,-(sp) mov r1,-(sp) mov r2,r1 ;copy clrb r1 swab r1 call prnum ;print bic #^C377,r2 ;isolate mov #chtab,r0 50$: cmp r2,(r0)+ ;is this it? beq 60$ ;yes tst (r0)+ br 50$ 60$: mov (r0)+,r0 .print mov (sp)+,r1 mov (sp)+,r0 sob r1,40$ ;loop br 20$ ; _ chtab: .word chdim,xdim .word chdim7,xdim7 .word chmin,xmin .word chmin7,xmin7 .word chmaj,xmaj .word chdom7,xdom7 .word chmaj7,xmaj7 .word chmin6,xmin6 .word chmaj6,xmaj6 ; xdim: .asciz / dim/ xdim7: .asciz / dim7/ xmin: .asciz / min/ xmin7: .asciz / min7/ xmaj: .asciz / maj/ xdom7: .asciz / dom7/ xmaj7: .asciz / maj7/ xmin6: .asciz / min6/ xmaj6: .asciz / maj6/ .even ;+ ; ; Get a char from KB buf into r0, skipping blanks and ctrl chars. ; ; C=1 if eol or comma. ; ;- getc: movb (r5)+,r0 ;get a char beq 10$ ;eol cmp r0,#<' > ;blank or cc? blos getc ;loop if so cmp r0,#', ;comma? beq 10$ ;yes, treat like eol clc ;C=0 rts pc 10$: dec r5 ;unget sec ;C=1 rts pc ; gtnum: clr r1 ;init # 10$: movb (r5)+,r0 ;get a char beq 20$ ;whoops cmp r0,#<' > ;blank or cc? blos 10$ ;ignore sub #'0,r0 ;convert cmp r0,#9. ;decimal? bhi 20$ ;no mul #10.,r1 ;*10 add r0,r1 ;add it in br 10$ ;loop 20$: dec r5 ;unget rts pc ; .sbttl search stuff ;+ ; ; Clear high score list. ; ;- clrscr: mov #hiscor,r0 ;pt at list mov #numhis*scrlen/2,r1 ;length 10$: clr (r0)+ ;zap sob r1,10$ ;loop rts pc ;+ ; ; Check string against high score list, possibly add it. ; ; r4 string to add ; r3 score ; r0 # of notes ; ; r5 is preserved. ; ;- chekhi: mov r5,-(sp) ;may have note string mov r0,newscr+numnot ;save mov r3,newscr+score mov r4,newscr+notstr ; scan the list to make sure we're not on it already mov #hiscor,r5 ;pt at list mov #numhis,r4 ;length 10$: tst notstr(r5) ;something here? beq 30$ ;no cmp newscr+numnot,numnot(r5) ;same # of notes? bne 30$ ;no cmp newscr+score,score(r5) ;same score? bne 30$ ;no mov newscr+notstr,r0 ;get 1st string mov notstr(r5),r1 ;2nd string mov numnot(r5),r2 ;length 20$: cmp (r0),(r1) ;same value/duratn fields? bne 30$ ;no, skip mov next(r0),r0 ;deref mov next(r1),r1 sob r2,20$ ;loop br 60$ ;they're equal, flush the new entry 30$: add #scrlen,r5 ;skip to next sob r4,10$ ;loop ; not on scoreboard, insert it if it belongs there mov #newscr-scrlen,r5 ;ptr mov #numhis,r3 ;count 40$: ; since we want to compare score per note (entries with more ; notes will tend to have higher scores since there are more ; intervals), ; we will cross multiply the total scores and string lengths tst notstr(r5) ;is this an empty entry? beq 50$ ;yes, don't bother comparing, we win mov (r5),r1 ;get score mul scrlen+numnot(r5),r1 ;yep mov r1,r0 ;copy mov scrlen+score(r5),r1 ;from both mul numnot(r5),r1 cmp r0,r1 ;(r5)>=scrlen(r5)? (*signed*) bge 60$ ;yep, we're done 50$: mov r5,r4 ;copy mov (r5)+,r0 ;exchange mov (r5)+,r1 mov (r5)+,r2 mov (r5)+,(r4)+ mov (r5)+,(r4)+ mov (r5)+,(r4)+ mov r0,(r4)+ mov r1,(r4)+ mov r2,(r4)+ sub #scrlen*3,r5 ;back up sob r3,40$ ;loop 60$: ; now flush whoever lost mov newscr+notstr,r0 ;get note list beq 80$ ;none, must have been a free slot in list 70$: mov next(r0),r1 ;copy retblk r0 ;lost it mov r1,r0 ;copy bne 70$ ;loop unless done 80$: mov (sp)+,r5 ;restore rts pc ;+ ; ; Pump out a few random notes. ; ; r5 string to match ; r1 NZ if new voice should be above r5, Z if below ; r0 # notes to generate ; ; Returns: ; r5 unchanged ; r4 string we found ; r3 score ; ;- rndnot: mov r5,-(sp) ;save string mov r0,-(sp) ;save # notes mov r1,-(sp) ;save flag call getblk ;get a block mov r0,r4 ;pt with r4 10$: ; pick a starting note which is a happy interval away ; from the starting note we're matching ; (why not cut our losses) mov #oct,r0 ;look within an octave call random ;get a random # movb (r5),r1 ;get curr note tst (sp) ;which way? bne 20$ ;above sub r0,r1 ;below br 30$ 20$: add r0,r1 ;above 30$: movb r1,(r4) ;save value movb duratn(r5),duratn(r4) ;copy duration call rate2 ;get new score tst r3 ;what do you think? bmi 10$ ;too sucky, try again tst (sp)+ ;lose flag mov r4,-(sp) ;throw this on stack too mov r3,-(sp) ;save score mov r3,-(sp) ;twice 40$: ; do next note dec 6(sp) ;done? beq 110$ ;yes call getblk ;get a block mov r4,prev(r0) ;link it in mov r0,next(r4) mov r0,r4 ;pt with r4 mov next(r5),r5 ;skip to next movb duratn(r5),duratn(r4) ;copy length 50$: ; decide how far to move now mov #4,r0 ;get [0,3] call random tst r0 ;stepwise for sure 3/4 of the time bne 80$ ;yep ; find out how far we may jump mov #oct,r0 ;up to an octave call random ;get max interval in r0 inc r0 ;+1 (fix bounds) call random ;get the interval mov r0,-(sp) ;save mov #2,r0 ;up or down? call random mov (sp)+,r1 ;recover mov prev(r4),r2 ;prev note movb (r2),r2 ;value tst r0 ;down? beq 60$ ;yep add r1,r2 ;up br 70$ ;skip 60$: sub r1,r2 ;down 70$: movb r2,(r4) ;go br 90$ ;skip 80$: ; stepwise motion (half or whole tone either way, or repeat) mov #5,r0 ;-2, -1, 0, +1, +2 call random ;[0,4] sub #2,r0 ;[-2,2] mov prev(r4),r1 ;prev note movb (r1),r1 ;value add r0,r1 ;add it movb r1,(r4) ;new value 90$: ; rate it call rate2 ;how's it look? tst r3 ;negative? bpl 100$ ;no tst 2(sp) ;was prev score negative? bmi 50$ ;yes, throw this note away 100$: add r3,(sp) ;add it in br 40$ ;loop 110$: ; done mov (sp)+,r3 ;score tst (sp)+ ;lose prev interval score mov (sp)+,r4 ;starting pos tst (sp)+ ;lose count (0 by now) mov (sp)+,r5 ;old r5 rts pc ;+ ; ; Rate a position. ; ; r5 ptr to top note in current chord ; r4 running score ; ;- rate: .rem _ mov r5,r3 ;copy mov #chbuf,r2 ;pt at buffer 10$: movb (r3)+,(r2)+ ;get note mov 5(r3),r3 ;get next in chord bne 10$ ;loop for all clrb (r2) ;mark end mov #chbuf,r5 ;pt at chord call chord ;look it up _ ;+ ; ; Rate a pair of voices. ; ; r5 upper voice ; r4 lower voice ; ; r3 returns score ; ;- rate2: clr r3 ;zap ; see if there's a preceding interval ; (there won't be if one of the voices is a new entrance) mov #-1,r2 ;no prev interval yet mov prev(r5),r0 ;get preceding upper voice beq 50$ ;none, never mind mov prev(r4),r1 ;same for lower beq 50$ ;none, don't worry about it ; there is is preceding interval movb (r0),r0 ;get the notes themselves movb (r1),r1 ; check motion and adjust score: ; contrary or one note stayed the same: +5 ; similar: -5 cmpb (r5),r0 ;has upper voice gone up or down? bhi 10$ ;up beq 30$ ;same cmpb (r4),r1 ;down, see if lower voice went up bhis 30$ ;yes br 20$ 10$: cmpb (r4),r1 ;u.v. went up, see if l.v. went down blo 30$ ;yes 20$: sub #10.,r3 ;score -5 (-10.+5) 30$: add #5,r3 ;score +5 40$: ; get previous interval into r2 sub r1,r0 ;find interval movb intrvl(r0),r2 ;normalize to .lt. 1 octave 50$: ; get current interval movb (r5),r0 ;upper movb (r4),r1 ;lower sub r1,r0 ;absolute interval movb intrvl(r0),r0 ;normalized to one octave ; prev interval in r2, current in r0 mov r2,r1 ;copy asl r1 ;*2 jmp @prvint(r1) ;maybe it's a special case .word cntcur ;there was no preceding interval prvint: .word cntcur ;unison .word cntcur ;minor 2nd .word pmaj2 ;major 2nd (lower resolves down to min3) .word cntcur ;minor 3rd .word cntcur ;major 3rd .word pperf4 ;perfect 4th (upper resolves down to maj3) .word cntcur ;tritone .word pperf5 ;perfect 5th .word cntcur ;minor 6th .word cntcur ;major 6th .word cntcur ;minor 7th (upper resolves down to maj6) ???? .word cntcur ;major 7th (upper resolves up to octave) ???? ; pperf5: ; perfect fifth asl r3 ;contrary motion is more important br cntcur ;continue processing ; ; basically we want to make sure 5/4/1 resolves to 5/3/1 .enabl lsb pmaj2: cmp r0,#min3 ;resolved to minor 3rd? bne 10$ ;no, points off cmpb @prev(r5),(r5) ;upper voice the same? bne 10$ ;no add #30.,r3 ;yes, bump their score br cntcur ; pperf4: cmp r0,#maj3 ;resolved to maj3? bne 10$ ;no cmpb @prev(r4),(r4) ;lower voice the same? bne 10$ ;no add #30.,r3 ;yes, bump score br cntcur ; 10$: ; they blew it, points off (but keep trying just in case) sub #50.,r3 ;screw their score ;br cntcur ;drop through to continue with curr interval .dsabl lsb ; cntcur: ; continue with current interval cmpb (r5),(r4) ;make sure voices are in right order bhis 10$ ;yep sub #50.,r3 ;bad otherwise 10$: ; see both notes are in key signature clr r1 ;0's bisb (r5),r1 ;get one movb colaps(r1),r1 ;collapse to 1 octave tstb keysig(r1) ;in key sig? bne 20$ ;yes sub #20.,r3 ;no, take off points 20$: clr r1 ;0's bisb (r4),r1 ;get other movb colaps(r1),r1 ;collapse to 1 octave tstb keysig(r1) ;in key sig? bne 30$ ;yes sub #5,r3 ;no, take off 30$: mov r0,r1 ;copy current interval asl r1 ;*2 jmp @curint(r1) ;vector curint: .word cunsn ;unison or octave - good (opposite directions) .word min20 ;min2 - bad .word plus20 ;maj2 - good but must resolve .word third ;min3 - good (no more than 3 in a row) .word third ;maj3 - good (no more than 3 in a row) .word plus20 ;perf4 - good but must resolve .word min20 ;tritone - bad .word fifth ;perf5 - good but no similar or || motion .word sixth ;min6 - good (no more than 3 in a row) .word sixth ;maj6 - good (no more than 3 in a row) .word min10 ;min7 - should we let it resolve to maj6? .word min10 ;maj7 - should we let it resolve to octave? ; min10: sub #10.,r3 ;points off rts pc ; min20: sub #20.,r3 ;points off rts pc ; plus20: add #20.,r3 ;+20. rts pc ; cunsn: tst r2 ;parallel octaves? beq 10$ ;yes, no change in score add #10.,r3 ;+10. 10$: rts pc ; third: add #30.,r3 ;good rts pc ; fifth: cmp r2,#perf5 ;parallel 5ths? beq 10$ ;ding ding ding ding ding add #25.,r3 ;+10. rts pc 10$: sub #50.,r3 ;-50. rts pc ; sixth: add #20.,r3 ;good rts pc ;+ ; ; Name that chord. ; ; On entry: ; r5 ptr to 0-terminated sorted note list ; ; On return: ; r0 ptr to list of possibilities ; r1 number of possibilities found ; ; For each note in the chord: ; collapse the others into the octave above that note, ; and build a mask of all the notes that appear at least once. ; since a word is 16 bits we can fit the whole octave (12 notes) ; in a single word. each bit represents a note, with the lowest ; note in the 1's bit, so that the word reads right to left ; (just because this is easier on the PDP-11). ; ; For chords of more than two distinct notes, there will usually ; be only one possible chord found. ; ;- chord: mov #chdlst,-(sp) ;init ptr mov r5,r4 ;copy addr of begn of list 10$: movb (r4)+,r0 ;get next bass note beq 80$ ;none, skip clr r1 ;init mask mov r5,r3 ;pt at begn of list 20$: movb (r3)+,r2 ;get a note beq 50$ ;none, skip ; calculate interval, normalize to octave above bass note sub r0,r2 ;subtract bass note bmi 40$ ;negative, skip 30$: sub #oct,r2 ;down an octave bpl 30$ ;loop until negative (1 too many) 40$: add #oct,r2 ;up an octave bmi 40$ ;loop until positive asl r2 ;*2 bis bits(r2),r1 ;set that bit in mask br 20$ ;loop 50$: ; r0=bass note, r1=mask for chord ; search chord table for first chord of which ; ours is a proper subset (i.e. missing notes are OK) ; (we check triads before 7ths so this won't add any ; new ambiguities) mov #chords,r3 ;point at list 60$: mov (r3),r2 ;get mask beq 10$ ;end of table, guess not (try next bass note) bis r1,r2 ;set our bits cmp r2,(r3)+ ;same (is our chord improper subset)? beq 70$ ;yes tst (r3)+ ;no, skip chord name br 60$ ;loop 70$: ; found a match swab r0 ;swap to high byte bisb (r3),r0 ;get type mov (sp)+,r2 ;get ptr mov r0,(r2)+ ;save chord mov r2,-(sp) ;save br 10$ ;next note 80$: mov #chdlst,r0 ;get ptr mov (sp)+,r1 ;curr ptr sub r0,r1 ;find # bytes saved asr r1 ;/2=# words rts pc .sbttl terminal I/O routines ;+ ; ; Note input routine. ; ; Return note list in r0 (0 if none). ; ;- notein: clr -(sp) ;zap note list clr r4 ;no prev yet mov #crtcht,r2 ;previous note value = crotchet mov #kbbuf,r5 ;pt at buf .gtlin r5,#ntprmp ;first prompt br 30$ ;skip 10$: .print #invinp ;pr msg 20$: mov #kbbuf,r5 ;pt at kbbuf .gtlin r5,#ntprm2 ;get a line 30$: call getc ;get a char bcs 20$ ;need another line bic #40,r0 ;cvt to upper sub #'A,r0 ;convert cmp r0,#6 ;A-G? bhi 10$ ;err movb offs(r0),r1 ;get offset call getc ;get a char bcs 10$ ;err cmp r0,#'# ;sharp? beq 40$ cmp r0,#'+ ;hm? bne 50$ 40$: ; sharp inc r1 ;yes, +1 br 60$ ;skip 50$: cmp r0,#'- ;flat? bne 70$ ; flat dec r1 ;-1 60$: call getc ;get another bcs 10$ ;error 70$: ; must be octave mov r1,-(sp) ;save sub #'0,r0 ;subtract base cmp r0,#9. ;good digit? bhi 10$ ;complain mov r0,r1 ;copy call getc ;another bcs 90$ ;skip sub #'0,r0 ;convert cmp r0,#9. ;good? bhi 80$ ;nope, skip mul #10.,r1 ;yes, high dig *10 add r0,r1 ;add this in inc r5 ;fakeout 80$: dec r5 ;unget 90$: mov r1,r0 ;copy back clr r1 ;zap bisb octs(r0),r1 ;get base add (sp)+,r1 ;find note ; get duration call getc ;get duration bcs 110$ ;use default bic #40,r0 ;cvt to upper mov r2,-(sp) ;save mov #durtab,r3 ;pt at table 100$: mov (r3)+,r2 ;get next beq 150$ ;err cmpb r0,r2 ;is this it? bne 100$ ;loop if not clrb r2 ;zap swab r2 ;low byte tst (sp)+ ;flush stack 110$: ; note duration in r2 call getc ;any more chars? bcs 120$ ;no ; . = multiply duration by 1.5 cmp r0,#'. ;dotted? bne 150$ ;no mov r2,r0 ;copy asr r0 ;/2 add r0,r2 ;*1.5 120$: ; store note call getblk ;get a block movb r1,(r0) ;save value movb r2,duratn(r0) ;duration mov r4,prev(r0) ;set prev beq 130$ ;none, skip mov r0,next(r4) ;save br 140$ ;skip 130$: mov r0,(sp) ;begn of list 140$: mov r0,r4 ;new prev cmpb (r5)+,#', ;comma? beq 30$ ;yes, get more mov (sp)+,r0 ;get begn of list rts pc 150$: mov (sp)+,r2 ;recover value br 10$ ;complain ; offs: .byte a,b,c,d,e,f,g octs: .byte oct0,oct1,oct2,oct3,oct4,oct5,oct6,oct7,oct8,oct9,oct10 .even durtab: .byte 'D,breve ;double whole .byte 'W,sbreve ;whole .byte 'H,minim ;half .byte 'Q,crtcht ;quarter .byte 'E,quaver ;eighth .byte 'S,sqvr ;sixteenth .byte 'T,dsqvr ;thirty-second .word 0 ;+ ; ; Display a note string. ; Same format used by NOTEIN. ; ; r5 ptr to head of voice ; ;- dispst: mov r5,r4 ;copy 10$: movb (r4),r3 ;get value clr r2 ;sxt div #12.,r2 ;divide asl r3 ;*2 .print ntnam(r3) ;print name mov r2,r1 ;get octave call prnum ;display movb duratn(r4),r2 ;get value mov #durtab,r1 ;pt at table 20$: movb (r1)+,r0 ;get letter beq 30$ ;whoops cmpb r2,(r1)+ ;is this it? bne 20$ ;loop if not br 40$ ;skip 30$: mov #'?,r0 ;don't know duration 40$: .ttyout ;display it mov next(r4),r4 ;get next note beq 50$ ;none, skip .ttyout ^!#',! ;comma .ttyout <#' > ;blank br 10$ ;loop 50$: .print #crlf ;end of string rts pc ; ntnam: .word 1$,2$,3$,4$,5$,6$,7$,8$,9$,10$,11$,12$ 1$: .ascii /C/<200> 2$: .ascii /C#/<200> 3$: .ascii /D/<200> 4$: .ascii /D#/<200> 5$: .ascii /E/<200> 6$: .ascii /F/<200> 7$: .ascii /F#/<200> 8$: .ascii /G/<200> 9$: .ascii /G#/<200> 10$: .ascii /A/<200> 11$: .ascii /A#/<200> 12$: .ascii /B/<200> .even .sbttl MIDI routines ;+ ; ; Play a note string. ; ; r5 ptr to head of note string ; ;- play: ; next time slice mov r5,r4 ;copy 10$: ; start next note in chord mov prev(r4),r0 ;get prev ptr beq 20$ ;none, skip tst flags(r0) ;is this note continued from prev? bmi 30$ ;yes, don't restrike 20$: mov #220,r0 ;note on call mput movb (r4),r0 ;(key) call mput mov #177,r0 ;max velocity call mput 30$: mov chnext(r4),r4 ;next in chord bne 10$ ;loop ; wait clr r0 ;zap bisb duratn(r5),r0 ;get duration mul #3,r0 ;* multiplier mov r0,delay ;save mov r1,delay+2 mov #mrkt,r0 ;pt at blk .mrkt ;start delay .spnd ;wait ; turn off all non-continued notes mov r5,r4 ;copy 40$: ; stop next note in chord tst flags(r4) ;continued? bmi 50$ ;yes, skip this one mov #200,r0 ;note off call mput movb (r4),r0 ;(key) call mput mov #177,r0 ;max velocity call mput 50$: mov chnext(r4),r4 ;get next chord bne 40$ ;loop until done ; around for next chord mov next(r5),r5 ;defer bne play ;loop rts pc ;+ ; ; Put a MIDI byte. ; ;- mput: tstb @#xcsr ;ready? bpl mput ;loop if not movb r0,@#xbuf ;write rts pc ;later ; tcrtn: ; timer completion routine .rsum ;restart mainline rts pc ; .sbttl utility routines ;+ ; ; Link a voice in below another voice. ; ; r5 existing voice ; r4 voice to link in ; ;- link: mov r5,-(sp) ;save ; link to end of preceding voice in this position mov prev(r5),r0 ;see if prev voice beq 10$ ;none, skip mov chnext(r0),r0 ;get its lower neighbor beq 10$ ;none mov r4,next(r0) ;link this to it mov r0,prev(r4) 10$: ; go through note by note and synchronize cmpb duratn(r4),duratn(r5) ;duration the same? beq 30$ ;yes, skip blo 60$ ;smaller, split everyone else ; larger, split our note in two pieces clr r0 ;get durations bisb duratn(r5),r0 clr r1 bisb duratn(r4),r1 sub r0,r1 ;find # left over movb r0,duratn(r4) ;truncate this note call getblk ;get another blk movb (r4),(r0) ;set pitch movb r1,duratn(r0) ;duration mov r4,prev(r0) ;link this in mov next(r4),r1 ;get next note beq 20$ ;none mov r1,next(r0) ;link it in mov r0,prev(r1) ;yep 20$: mov flags(r4),flags(r0) ;copy flags bis #cont,flags(r4) ;previous note is continued 30$: ; equal, just link us in mov r5,chprev(r4) ;yep mov chnext(r5),r0 ;get their lower neighbor beq 40$ ;skip mov r0,chnext(r4) ;link it in mov r4,chprev(r0) ;us to them too 40$: mov r4,chnext(r5) ;link us to u.n. mov next(r5),r5 ;skip beq 50$ ;whoops mov next(r4),r4 ;link bne 10$ ;loop 50$: mov (sp)+,r5 ;restore r5 rts pc 60$: ; our note is too short to fit ; hack up the other notes bpt ;+ ; ; Get and zero a note block, return ptr in r0. ; ; All other regs preserved. ; ;- getblk: mov r1,-(sp) ;save mov freblk,r0 ;get a blk beq 30$ ;whoops mov (r0),freblk ;save 10$: mov #length/2,r1 ;length 20$: clr (r0)+ ;zap sob r1,20$ ;loop sub #length,r0 ;back up mov (sp)+,r1 ;restore rts pc 30$: ; allocate more core bpt ;punt ;+ ; ; Print # in r1. ; ;- prnum: tst r1 ;negative? bpl 10$ ;no .ttyout #'- ;yes neg r1 ;|r1| 10$: clr r0 ;sxt div #10.,r0 ;divide bis #'0,r1 ;cvt tst r0 ;more? beq 20$ ;no mov r1,-(sp) ;save mov r0,r1 ;copy call 10$ ;recurse mov (sp)+,r1 ;restore 20$: .ttyout r1 ;display rts pc ;+ ; ; Random number from 0 to r0. ; ; Return in r0. ; ;- random: tst r0 ;nothing? beq 10$ ;yep mov seed,r1 ;get seed mul #257.,r1 ;this never works... add #11.,r1 mov r1,seed ;store it back mov r0,r2 ;save clr r0 ;sxt div r2,r0 ;divide mov r1,r0 ;copy remainder 10$: rts pc ; chords: .word bmaj,chmaj .word bmaj7,chmaj7 .word bdom7,chdom7 .word bmin,chmin .word bmin7,chmin7 .word bdim,chdim .word bdim7,chdim7 .word bmaj6,chmaj6 .word bmin6,chmin6 .word 0 ; bits: .word 1,2,4,10,20,40,100,200,400,1000,2000,4000 ;1st 12 bits ; collapsing lookup table. collapses all notes into one octave colaps: .byte 0,1,2,3 ;rest is from INTRVL ; interval lookup table. collapses all intervals into one octave. .byte 4,5,6,7,10,11,12,13 .rept 10. .byte 0,1,2,3,4,5,6,7,10,11,12,13 .endr intrvl: .rept 10. .byte 0,1,2,3,4,5,6,7,10,11,12,13 .endr .byte 0,1,2,3,4,5,6,7 ; hello: .asciz /Themefit by John Wilson/ ; crlf: .byte 0 ; ntprmp: .ascii 'string: '<200> ntprm2: .ascii ' : '<200> invinp: .asciz 'Invalid input' ; .even gtim: .byte 0,21 ;.GTIM .word time ;put it at TIME ; mrkt: .byte 0,22 ;.MRKT .word delay ;addr of time .word tcrtn ;completion routine .word 1 ;ID ; keysig: .byte 1,0,1,0,1,1,0,1,0,1,0,1 ;1 for notes in key sig ; .even freblk: .blkw ;free block list ; time: .blkw ;time in 60th's (high order first) seed: .blkw ;low word of time (should be random enough) ; delay: .blkw 2 ;delay for .MRKT ; hiscor: .blkw numhis*scrlen/2 ;high score list newscr: .blkw scrlen/2 ;new entry to maybe add - must follow HISCOR ; chdlst: .blkw 10. ;chord list kbbuf: .blkb 80. ;KB buffer blocks: .blkw 1000. ;block buffer blklen= .-blocks ; .end start -------------------------------------------------------------------------- 16) More PDP-11 Synthesizer HW and SW Information ------------------------------------------------- Contributor: Megan Gentry, mbg@world.std.com "Years ago, I got ahold of the TI sound generation controller and was able to wire up a crude circuit which drove it from a DR11C. A friend who was much more versed in electronic design created a circuit (which we dubbed the MK11-B, in honor of the MK10 music kludge) which could control multiple SGCs. I further modified it to drive a set of LEDs so that I had a programmable display." "Anyway, another friend wrote a program which compiled and played music source files of the same form as the Stanford music compiler for the DECsystem-10. It's been a few years since I last had the board operating, but I think I still have the engineering drawings for the circuit." "Another friend of mine designed a circuit which would run off a DLV11-J (also modified) and allow the control of MIDI devices..." "I'll have to look into the software and see if my friend still has it available and would be willing to distribute it..." "And if I can find the circuit diagram for the 'MK11-B', I'll try to post it (somehow). I don't know if there is a hard copy of the circuit for the MIDI controller..." -------------------------------------------------------------------------- 17a) Computer Music Languages, part I ------------------------------------- Contributor: William Alves, alves@calvin.usc.edu "I once tried to compile a list of computer music languages, which I've included below. I've posted it in the hopes that it will be useful and that some readers out there can help fill in the missing information or correct any mistakes. It brings up interesting questions about what, exactly, is a computer music language. But I'll leave that to you to decide. It's roughly in chronological order." [Editor's note: I've deleted all non-PDP related languages that were in the original file from which I extracted this PDP-related information, but they can be found in the complete, original, file in my FTP/WWW archive: Music-Languages*. RDD] "SUMMARY LISTING OF COMPUTER MUSIC LANGUAGES Computer Author(s) Language or OS Language Year (Institution) OUTPERFORM PDP-11 FORTRAN IV 1972 D. Jaeger, D. Lester (University of Toronto) MUSIC7 PDP-8 FORTRAN IV ? L. Hiller (SUNY Buffalo) MUSIC 10 PDP-10 ? ? J. Chowning, A. Moorer (Stanford) MUSIC 11 DEC PDP-11 Macro-II 1973 Barry Vercoe (MIT) MUS10 PDP-10 FORTRAN IV 1974 Leland Smith (Stanford) & MACRO 10 SSP PDP-15/20 MACRO-15 1975 G. M. Koeniq (Insti- tute of Sonology, Utrecht) MUSCMP DEC PDP-11 SAIL ? (Stanford) PILE DEC PDP-15 Macro 1977 Paul Berg (Institute of Sonology, Utrecht) SYNTA L-II PDP-10 FORTRAN IV 1977 W. Slawson (Univ. of Pittsburgh) PLAY1 DEC PDP-11 PDP-11 1977 Joel Chadabe and Roger assembler Myers (NYSU Albany) PLAY2 DEC PDP-11? XPL 1978 Joel Chadabe and Roger Myers (NYSU Albany) SYN4B DEC LSI-11 LSI-11 1978 N. Rolnick (IRCAM) assembler CHANT DEC PDP-11 SAIL 1979 Xavier Rodet, Yves Potard, and Conrad Cummings (IRCAM) MUSIC 1000 DEC PDP-11 ? 1979 Dean Walraff (DMX) 4CED DEC PDP-11 MACRO-11? 1979 Curtis Abbott (IRCAM) "[WA] ---------------------------------------------------------------------------- 17b) Computer Music Languages, part II --------------------------------------- Contributor: Carter Scholz, csz@well.sf.ca.us "Earlier this year I volunteered to compile a list of music composition languages, based on responses from the Net. Thanks to all who responded, especially Bill Alves and Roger Dannenberg, who submitted the bulk of these entries, and suggested a format. This list makes no pretense to completeness, timeliness, usefulness, or to defining what a computer music language is or is not. It is simply an unedited compilation of data that Internet users chose to send me after reading my query about computer music languages. If you have additions, emendations, or suggestions, I'll be happy to hear them, and if I have the time I'll update the list sometime in the future." [Editor's note: I've deleted all non-PDP related languages that were in the original file from which I extracted this PDP-related information, but they can be found in the complete, original, file in my FTP/WWW archive: Music-Languages*. RDD] "======================== Language: OUTPERFORM Computer or OS: PDP-11 Language: Fortran IV Year: 1972 Author: D. Jaeger, D. Lester (University of Toronto) Reference: Description: From: alves%calvin.usc.edu%usc%elroy.jpl.nasa.gov@com.dec.decwrl (William Alves) Language: MUSIC7 Computer or OS: PDP-8 Language: Forran IV Year: Author: Lejaren Hiller (SUNY Buffalo) Reference: Description: From: alves%calvin.usc.edu%usc%elroy.jpl.nasa.gov@com.dec.decwrl (William Alves) Language: MUSIC 10 Computer or OS: PDP-10 Language: Year: Author: J. Chowning, A. Moorer (Stanford) Reference: Description: From: alves%calvin.usc.edu%usc%elroy.jpl.nasa.gov@com.dec.decwrl (William Alves) Language: MUSIC 11 Computer or OS: DEC PDP-11 Language: Macro-II [Editor's note: this should be Macro-11. RDD] Year: 1973 Author: Barry Vercoe (MIT) Reference: Description: From: alves%calvin.usc.edu%usc%elroy.jpl.nasa.gov@com.dec.decwrl (William Alves) Language: MUS10 Computer or OS: PDP-10 Language: Fortran IV Year: 1974 Author: Leland Smith (Stanford) Reference: Description: From: alves%calvin.usc.edu%usc%elroy.jpl.nasa.gov@com.dec.decwrl (William Alves) Language: SSP Computer or OS: PDP-15/20 Language: Macro-15 Year: 1975 Author: G. M. Koenig (Inst. of Sonology, Utrecht) Reference: Description: From: alves%calvin.usc.edu%usc%elroy.jpl.nasa.gov@com.dec.decwrl (William Alves) Language: MUSCMP Computer or OS: DEC PDP-11 Language: SAIL Year: Author: Reference: Description: From: alves%calvin.usc.edu%usc%elroy.jpl.nasa.gov@com.dec.decwrl (William Alves) Language: PILE Computer or OS: DEC PDP-15 Language: Macro Year: 1977 Author: Paul Berg (Inst. of Sonology, Utrecht) Reference: Description: From: alves%calvin.usc.edu%usc%elroy.jpl.nasa.gov@com.dec.decwrl (William Alves) Language: SYNTA L-II Computer or OS: PDP-10 Language: Fortran IV Year: 1977 Author: Wayne Slawson (U of Pittsburgh) Reference: Description: From: alves%calvin.usc.edu%usc%elroy.jpl.nasa.gov@com.dec.decwrl (William Alves) Language: PLAY1, PLAY2 Computer or OS: DEC PDP-11 Language: XPL Year: 1977-8 Author: Joel Chadabe & Roger Myers (NYSU Albany) Reference: Description: From: alves%calvin.usc.edu%usc%elroy.jpl.nasa.gov@com.dec.decwrl (William Alves) Language: SYN4B Computer: LSI-11/03 Language: LSI-11 assembler Year: 1978 Author: Neil Rolnick & Phillipe Prevot (IRCAM) Reference: Computer Music Journal 2:2 Description: From: alves%calvin.usc.edu%usc%elroy.jpl.nasa.gov@com.dec.decwrl (William Alves) Language: Music-1000 Computer or OS: LSI-11 Language: LSI-11 assembler Year: 1978 Author: Dean Wallraff Reference: 3:4 Description: Score and orchestra language for DMX-1000 signal processor. From: Language: CHANT Computer or OS: PDP-11 Language: SAIL Year: 1979 Author: Xavier Rodet , Yves Potard, Conrad Cummings (IRCAM) Reference: Computer Music Journal Description: From: alves%calvin.usc.edu%usc%elroy.jpl.nasa.gov@com.dec.decwrl (William Alves) Language: 4CED Computer or OS: PDP-11 Language: Macro-11? Year: 1979 Author: Curtis Abbott Reference: Description: From: alves%calvin.usc.edu%usc%elroy.jpl.nasa.gov@com.dec.decwrl (William Alves) =========== END ==========="[CS] ---------------------------------------------------------------------------- 18) Groupe de Recherches Musicales ---------------------------------- Contributor: Jean-Yves Bernier, bernier@dialup.francenet.fr "Lately, but for the sake of completeness: A PDP11/60 was used by the Groupe de Recherches Musicales in Paris, around 1980-85. A couple of stereophonic AD/DA was interfaced to a DR-11. Sounds were recorded on 70Mb RP02's, processed by FORTRAN programs, and played back to tape. Later, J.F.Allouis engineered a Unibus real-time processing board and software, called SYTER. Then a Q-bus version was derived and marketed. Main customers were music schools (Conservatoires) as well as research institutes (Laboratoire d'Acoustique et Mecanique, Marseille, J.C.Risset). Musicians at the Groupe de Recherches Musicales used SYTER widely in their Musique Concrete production, as many records attest. WHen I left the Groupe, parts of this work had been ported on the Mac/56000 platform. Parts were lost." [JY-B] ========================================================================== End of Summary ==========================================================================