Jump to content


+AtariAge Subscriber
  • Content Count

  • Joined

  • Last visited

Community Reputation

98 Excellent

About k-Pack

  • Rank
    Chopper Commander

Profile Information

  • Gender
  • Location
    Buffalo, New York
  • Interests
    Diamond GOS, MIDI, hobby electronics, keeping the Atari equipment running, bicycling, Atari sound
  • Currently Playing
    MIDI Music System
    Diamond GOS
  • Playing Next
    Experiment with dGOS and MIDI
    Build dGOS 8-bit step sequencer for SX-150 Mark II
    Wii Guitar as Atari game controler
    recreate Switched on Bach play list

Recent Profile Visitors

12,794 profile views
  1. A major rewrite of the Arduino/Atari communication software was accomplished. It seems the Cassette Motor Control pin causes a spike when it switched. (You can hear it in some of the previous tracks.) BIT 7 of PORTA has been configured for output. Joystick 2 trigger can be used as BIT 7 if its ever needed. It took a couple of weeks of software trouble shooting to figure out that the hardware was the problem. The output power from the CMC was enough to trigger the optocoupler but the power from the joystick port was not. A resister was changed and the software seemed to be working the way it should. There still seems to be a click but is a little less noticeable. Sorry, I wasn't going to get technical. Brandenburg no3 First Movement.mp3 NOTES: Music File origin: BRAND.MUS - thanks to unknown person TRACK10.MUS - Recorded Control Computer: 130XE Sequencer Software: MIDI Music System by Lee Actor Voice 1 - PAT5 Voice 2 - PAT6 Voice 3 - PAT7 Voice 4 - PAT8 MIDI out: MIDIMAX Sound Source: Atari 130XE (#2) MIDI in: Arduino Software: MONOSYN_1-Byte_Data_rC.ino Monitor output to mixer Software: ADSR0D.M65 (recompiled for voice settings) (.Included READMIDC.M65) - PAT5.OBJ PAT6.OBJ PAT7.OBJ PAT8.OBJ Loaded from ATARIMAX Cart. Mixer: Behringer Xenyx 1202 FX Mic One input - Atari monitor port FX : #3 MID HALL 1 Recorder: PC - Audacity 2.1.2 File: Brandenburg no3 First Movement.aup - Sync tracks and trim TRACK10.atrTRACK10.atr
  2. It should work if the Atari can handle the power requirements of the ATMega. I have no idea what the power requirement is or how much the Atari can provide. Since there is only one power source the optocouplers haven't isolated the two circuits; replacing the optocouplers with transistors would probably be a better choice.
  3. The ground would be pin 8 of the atari joystick ports. The transisters are replacing the switches in the joystick. They are being turned on and off by the LEDs.
  4. There might be some information you will find interesting in this blog entry. I have had the Arduino hooked up to the Atari for several projects in several different ways. I generally like to use optocouplers between the Atari and Arduino for the safety factor they provide. This particular optocoupler works well enough for setting the inputs. Its a little hit and miss when used when the Atari joystick pins are set for output.
  5. A little tremolo was added to SINGLEBYTE.M65. It is subtle but hearable. Wachet.mp3 Work files TRACK09.atr NOTES: Music File origin: WICHET.AMS - thanks to unknown person converted to MMS - WICHET.MUS Control Computer: 130XE Sequencer Software: MIDI Music System by Lee Actor MIDI out: MIDIMAX Sound Source: Atari 130XE (#2) MIDI in: Arduino Software: MONOSYN_1-Byte_Data.ino Monitor output to mixer Software: SBTREMO.M65 SBTREMO.OBJ delay modified for voices Loaded from ATARIMAX Cart. Mixer: Behringer Xenyx 1202 FX Mic One input - Atari monitor port FX : #6 BIG HALL 1 Recorder: PC - Audacity 2.1.2 File: Wachet.aup Sound Edit - Sync tracks and trim - Pan and fade out
  6. I have spent a little time looking through some ATARI Assembly Language books for sound routines that I might find useful. I found several examples in ATARI Assembly Language Programmer's Guide by Allan Moose and Marian Lorenz. Chapter 5, appropriately titled "Sound", has 3 programs that I wanted to hear. BOX 31 - Envelope, BOX 32 - Tremolo, and BOX 33 - Vibrato. These are BASIC examples using USR routines. The ml programs were listed in BOX31A, BOX32A, and BOX33A. The first program was typed in and I got that "What the #@%!?" feeling when I typed RUN. It didn't work. As I was checking for my typos that feeling was slowly replaced with a DajaVue. I was back to "What the #@%!?" when I couldn't find a typo. I started feeling nostalgic about half way through trying to follow the ML logic and determining if it matched the DATA statements. Euphoria washed away several hours of frustration as I listened to the sound with an envelope. Now I realized, it is the search for euphoria that is drawing me back to my Atari age of computing. Spoiler Alert- If you too are looking for your euphoria then avoid downloading this ATR. It contains a working version of the BASIC programs with slight modifications and the USR routine source code in MAC/65 format. SOUND Box 31-33a.atr
  7. Seems the simpler the program the more I like the result. Prelude and fugue No2 in C Minor.mp3 Atari MUS and OBJ files SOPT8.atr NOTES: Music File origin: PANDF2R.MUS - entered from sheet music into MMS Control Computer: 130XE Sequencer Software: MIDI Music System by Lee Actor MIDI out: MIDIMAX Sound Source: Atari 130XE (#2) MIDI in: Arduino Software: MONOSNY_1-Byte_Data.ino Monitor output to mixer Software: SINGBYTE.M65 SINGBYTE.OBJ Loaded from ATARIMAX Cart. Mixer: Behringer Xenyx 1202 FX Mic One input - Atari monitor port FX : #3 MID HALL 1 Recorder: PC - Audacity 2.1.2 File: pandf2.aup Sound Edit - Sync tracks and trim - Pan and fade out
  8. Do you remember me mentioning that the first attempt to write a machine language program to read MIDI data delivered to the Atari joystick port was a complete failure? The Arduino hardware has remained the same. The joystick trigger and cassette motor control(CMC) pin on the SIO port are still being used to control data flow. But this time I redefined the project specs to simplify the ML program and tested the ML data transfer routine as a USR call. The USR routine was written to replace the BASIC code that checked the joystick trigger to see if data is ready to be read, gets the data, and tells the Arduino to get the next byte by setting the CMC. (the subroutine starting at line 100 in many of the earlier programs) The data byte is stored in a page Zero location to be PEEKed after control is returned to BASIC. Once working as a USR call the PLA was removed and the M65 file was edited and saved for later inclusion in the Project file as a subroutine. #INCLUDEd READMIDI.M65 routine is as follows: READMIDI.M65 01 ;USR FUNCTION TO GET MIDI DATA FROM02 ;ARDUINO BOARD WITH DATA FLOW CNTRL03 ;DATA RETURNED IN LOCATION $CB04 ;05 ;Kevin Packard 4/201906 ;0100 ;STRIG0 = $0284 -ARDUINO DSR0110 ;PORTA = $D300 -JOYSTICK INPUT0120 ;PACTL = $D302 -SIGNIAL ARDUINO0130 ;0140 READMIDI0150 MU1 LDA $0284 ;STRIG00160 CMP #00170 BEQ MU1 ;WAIT FOR DATA0180 LDA $D300 ;PORTA-READ DATA0190 STA $CB ;STORE BYTE PEEK(203)0200 LDA #52 ;DATA READ0210 STA $D302 ;PACTL-CMC ON0220 MU2 LDA $0284 ;STRIG00230 CMP #10240 BEQ MU2 ;LOOP TILL RESET0250 LDA #60 ;TURNS OFF BYTE0260 STA $D302 ;PACTL - CMC OFF0270 RTS ;RETURN Playing a MIDI note on the monophonic-Atari in its simplest form consists of receiving the MIDI note number for the tone to play or to turn the tone off . If you assume the volume value to be the same for every note then the volume data doesn't have to be sent. Since a MIDI note can have a value of 0 - 127, passing a value of 128 can be used to signal note off. The Arduino had to be reprogramed to minimize the data being sent to the Atari. The Arduino will first look for MIDI data for channel one. If its a NOTEON or NOTEOFF command it reads the following MIDI note number and then the volume byte. It then makes the decision to send a note number to start or change the pitch OR turn off the note being played. The logic makes sense considering a NOTEOFF command can be transmitted for a note that isn't being played or a NOTEON can set the volume to ZERO. /*Mono synth - channel 1 * Sends: * MIDI Note number to play * or * Bit 7 ON(128) to turn off note * * Kevin Packard May 2019 */// Atari PORTA(54016) mapped to pins on arduinoint porta0 = 4;int porta1 = 5;int porta2 = 6;int porta3 = 7;int porta4 = 8;int porta5 = 9;int porta6 = 10;int porta7 = 11;int DSR = 3; //data set ready triggerint DTR = 13;//Atari ready cmc byte zero = 0;byte midiData = 0;byte midiCommand = 0;byte midiNoteNum = 0;byte lastMidiNoteNum = 0;byte volume = 0;byte volOff = 128; //Function to Send a byte to the Atarivoid sendByte(byte byteToSend){ setPorta(byteToSend); digitalWrite(DSR,LOW); //data ready-Trigger 0 while(digitalRead(DTR) == LOW){} //Wait for Atari to get byte cmc goes low digitalWrite(DSR,HIGH); //data not ready-trigger 1 while(digitalRead(DTR) == HIGH){} //wait for Atari to signal ok to get next byte} void setPorta(byte byteToMap){ // Sets digital pins to transfer data to Atari joystick ports(PORTA) // When digital port high, joystick pin shorted to ground or logic 0 if (byteToMap & B00000001){digitalWrite(porta0,LOW);} else {digitalWrite(porta0,HIGH);} if (byteToMap & B00000010){digitalWrite(porta1,LOW);} else {digitalWrite(porta1,HIGH);} if (byteToMap & B00000100){digitalWrite(porta2,LOW);} else {digitalWrite(porta2,HIGH);} if (byteToMap & B00001000){digitalWrite(porta3,LOW);} else {digitalWrite(porta3,HIGH);} if (byteToMap & B00010000){digitalWrite(porta4,LOW);} else {digitalWrite(porta4,HIGH);} if (byteToMap & B00100000){digitalWrite(porta5,LOW);} else {digitalWrite(porta5,HIGH);} if (byteToMap & B01000000){digitalWrite(porta6,LOW);} else {digitalWrite(porta6,HIGH);} if (byteToMap & B10000000){digitalWrite(porta7,LOW);} else {digitalWrite(porta7,HIGH);}} void setup() { pinMode(porta0,OUTPUT); pinMode(porta1,OUTPUT); pinMode(porta2,OUTPUT); pinMode(porta3,OUTPUT); pinMode(porta4,OUTPUT); pinMode(porta5,OUTPUT); pinMode(porta6,OUTPUT); pinMode(porta7,OUTPUT); pinMode(DSR,OUTPUT); pinMode(DTR,INPUT); Serial.begin(31250); setPorta(zero);// digitalWrite(DSR,HIGH);} void loop() { //read data until its a Midi command //command bytes will have bit 7 true while (midiCommand != 128 && midiCommand != 144){ //midi command + Channel while(Serial.available()<1){}//wait for data midiCommand = Serial.read(); //read MIDI stream } // get data required by command. while(Serial.available()<1){} midiNoteNum = Serial.read(); while(Serial.available()<1){} volume = Serial.read(); if(midiNoteNum == lastMidiNoteNum && ((midiCommand == 128) || (midiCommand == 144 && volume == 0))){ sendByte(volOff); lastMidiNoteNum = 0; } if(midiCommand == 144 && volume > 0 && midiNoteNum != lastMidiNoteNum){ sendByte(midiNoteNum); lastMidiNoteNum = midiNoteNum; } midiCommand = 0;} // End of Listing The Atari now simply has to wait for the Arduino to set the trigger as new data is ready to be received. It then will turn off the sound, turn on the note, or change the pitch. The response time seems to be much faster then the compiled BASIC program. The Arduino"s data buffer didn't get overwritten when I ran my fingers up and down the keyboard or mashed down a bunch of keys over and over. I did note a bit of a delay as the buffer emptied. SINGBYTE.M65 0100 ;MIDI SYNTH MONO VOICE0110 ;ARDUINO 8BIT INPUT/CMC CONTROL0120 ; Monosyn_1-Byte_Data.ino0130 ;K-PACK 20190140 ;0150 STRIG0 = $02840160 AUDCTL = $D208 ;SET TO 120 - 16BIT FREQUENCEY DEFINITIONS0170 AUDF1 = $D200 ;LOWBIT- VOICE 10180 AUDF2 = $D202 ;HIBIT - VOICE 10190 AUDC2 = $D203 ;VEL-DIS-VOICE 10200 AUDF3 = $D204 ;LOWBIT- VOICE 20210 AUDF4 = $D206 ;HIBIT - VOICE 20220 AUDC4 = $D207 ;VEL-DIS-VOICE20230 SKCTL = $D20F0240 PORTA = $D300 ;JOYSTICKS VALUE0250 PACTL = $D302 ;CMC 60-OFF 52-ON0260 CMCON = 520270 CMCOFF = 600280 MIDIBYTE = $CB0290 ;0300 *= $40000310 .INCLUDE #D:FREQTABL.M650320 .INCLUDE #D:READMIDI.M650330 ;0340 ;0350 ;0360 START0370 LDA #0 ;RESET AUDIO0380 STA AUDCTL0390 LDA #30400 STA SKCTL0410 LDA #1200420 STA AUDCTL ;SET 16 BIT SOUND0430 LDA #CMCOFF0440 STA PACTL ;SET CASS MOTOR0442 LDA #00444 STA $022F ;kill SCREEN0450 ;MAIN LOOP0460 JP1 JSR READMIDI0470 LDA MIDIBYTE0490 CMP #128 ;NOTE OFF?0500 BNE JP20502 LDX #00505 STX AUDC20520 JMP JP1 ;GET NEXT DATA0530 JP2 LDX MIDIBYTE ;OFFSET FREQ TABLE0540 LDA FREQLO,X ;SET FREQ0550 STA AUDF10560 LDA FREQHI,X0570 STA AUDF20590 LDX #173 ;DIS=10 VOL=130600 STX AUDC2 ;TURN SET VOL0610 JMP JP1 ;NEXT COMMAND BYTE0620 ;0630 *= $02E20640 .WORD START0650 .END I'm hoping this program will be a good start for some interesting routines to modulate the sounds. A sound recording didn't seem to be necessary and the Arduino interface has been explained in previous blog entries. The atr file contains the MAC/65 files and BASIC files used to create and test the USR input routine. mls01.atr
  9. I'm pretty sure that pokey is used as a clock for the sio. Can't be used for both at the same time.
  10. When I see code like that it turns my mind to mush resulting in gibberish. That's my story and I'm sticking to it.
  11. Once I see c it's hard to unsee it.
  12. This track may seem a little plucky but if you listen to the tracks in order your ears may become conditioned to the point where it doesn't sound half bad. Or maybe not. prelude and fugue No7 in E-Flat Major.mp3 All the rest of the music has been entered into the MIDI Music System and is ready to record once some new sounds can be programed. For this track minor changes to the BASIC software was made to give a quick pluck or hit sound. I was a little supprised that a delay loop was needed when the program was compiled. This is the code that produces the sound. It occures so quickly that there didn't seem to be much need to check for a new note during the play period. The effects processor on the mixer was used to add some depth to the sound. REM VOL IS DISTORTION+ VOLUME 960 POKE AUDF1,LOBYTE(MIDINOTE) 970 POKE AUDF2,HIBYTE(MIDINOTE) 971 LASTNOTE=MIDINOTE 975 FOR VOL=160 TO 175 STEP 1:POKE AUDC2,VOL:FOR X2=1 TO 4:NEXT X2:NEXT VOL 976 FOR X2=1 TO 4:NEXT X2 978 FOR VOL=175 TO 160 STEP -1:POKE AUDC2,VOL:FOR X2=1 TO 4:NEXT X2:NEXT VOL The .MUS and program files are on the .ATR. The prelude and fugue were enter into different files and then combined in PANDF07.MUS for recording. TRACK07B.atr PRODUCTION NOTES: Music File origin: PANDF07.MUS - entered from sheet music into MMS Control Computer: 130XE Sequencer Software: MIDI Music System by Lee Actor MIDI out: MIDIMAX Sound Source: Atari 130XE (#2) MIDI in: Arduino Software: MonoSyn_1voice. ino Monitor output to mixer Software: T7VA4.OBJ - MMG compiled Atari BASIC program Loaded from ATARIMAX Cart. Mixer: Behringer Xenyx 1202 FX Mic One input - Atari monitor port FX : Voice 1-3 #85 Phaser + Reverb 2 Voice 4 #09 Church Recorder: PC - Audacity 2.1.2 File: prelude and fugue No7 in E-Flat Major.aup Sound Edit - Sync tracks and trim - Pan 40%L-40%R-10%L-10%R
  13. k-Pack

    SAM sings a round

    I had the same problem with singing SAM when I did this blog entry. http://atariage.com/forums/blog/572/entry-14044-sam-raaks-yuw/ Each word had to be modified for pitch and speed to get it to sound as good as it did. I would not want to do that much work for even the shortest song. I played around with a speech synthisizer chip from China. It came on an Arduino Shield and the instructions were almost useless to me. It is understandable in English. I used an RS-232 interface to transfer data to the shield. I haven't touched it since I wrote this series of blog entries. http://atariage.com/forums/blog/572/entry-13560-the-42107-voice-synthesizer/ http://atariage.com/forums/blog/572/entry-13602-type-talk-just-3-lines-of-basic-code/ http://atariage.com/forums/blog/572/entry-13654-the-voice-synthesizer-before-i-move-on/ I guess you can't make SAM sound to good and still have him sound like SAM.
  14. k-Pack

    SAM sings a round

    There was a Korg microKorg under the Christmas tree last year; only because my wife wouldn't let me set it up in November when it was purchased. I did manage to get the manual out of the box before it was wrapped. So for a whole month I read the manual and watched youTube videos. The microKorg has a vocoder. This suggested that the audio output from an Atari running SAM could be hooked up to the line-in on the Korg. Then the Korg could modifiy, modulate, or magically manipulate the signal to yet unheard sonic stimulations. Singing has never been one of SAM's strengths. But if auto-tune can make SAM sound this good then maybe I could have been a pop star. The score for "Row Row Row" was in the book "The Musical Atari" by Hal Glicksman, with music arranged by Laura Goodfriend (cc1984) and it seemed like a good place to start the experiments. The factory preset (A-85 Vocoder Chorus) was used to modify the input. I was a bit supprised. Sam ROW.mp3 In case you can't remember what SAM sounds like, the input to the vocoder is in this next file. Sam ROW- vocoder input.mp3 This was fun but I can't see SAM being my vocalist of choice. There is a chance that a few program changes and the use of the speed control POKE could change my mind. How it was done. The score was programmed into MIDI MUSIC SYSTEM software. Voice 1 was the music and was sent to the Korg as MIDI data to play. Voice 2 was programmed to output timing notes on channel 3 to an Arduino. The Arduino would then change the logic state on the STRIG(0) to let the Atari know it should speak the next word. The MIDI data flowed from the MIDIMax interface to the Korg and out the THRU port to the Arduino. The song was recorded twice. Once starting at middle C and then an octave lower. Then they were offset to produce the round. I have used the arduino interface a couple of times in the past to trigger events. This is just one optocoupler hooked up between the Arduino and Joystick port trigger. http://atariage.com/forums/blog/572/entry-14044-sam-raaks-yuw/ The Arduino runs this program to read the NOTEON data and set the trigger /* SAM Trigger * This program accepts MIDI data to sequence SAM voice. * * When a NOTE ON command for the sellected channel is * detected, the joystick trigger is turned on for * 50 milliseconds to trigger the next word to be said. */ int trigger = 3; byte midiData = 0; byte noteOnCommand = 146; //number representing channel and Command // 144(noteon)+2(channel 3) void setup() { pinMode(trigger,OUTPUT); digitalWrite(trigger,LOW); Serial.begin(31250); } void loop() { while(Serial.available()<1){}//wait for data midiData = Serial.read(); if (midiData == noteOnCommand){ // Note On - Channel digitalWrite(trigger,HIGH); delay(50);// give atari a chance to read joystick } else{ digitalWrite(trigger,LOW); // reset for next word } } The SAM-Atari runs the following. 1 REM SAM ROW VOICE TRIGGERED BY MIDI 2 REM ---kPack 2019 3 REM Arduino monitors midi input and 4 REM sets trigger when word is to be 6 REM said. Audio output from Atari 7 REM is connected to line-in on the 8 REM microKorg. 10 DIM SAM$(255):SAM=8192 15 POKE 8208,50 20 RESTORE 1000:TRAP 20 30 READ SAM$ 35 IF STRIG(0)=1 THEN 35 40 A=USR(SAM) 50 IF STRIG(0)=0 THEN 50 60 GOTO 30 70 REM 1000 DATA ROHW,ROHW,ROHW 1030 DATA YOHWR,BOH4T5 1040 DATA JEH5NT,LIY 1050 DATA DAWN1 1060 DATA DHAH4 1070 DATA STRIY4MM 1080 DATA MEHERAXLIY 1090 DATA MEHERAXLIY 1100 DATA MEHERAXLIY 1110 DATA MEHERAXLIY 1120 DATA LAY4F 1130 DATA IH4SS 1140 DATA BAA4T 1150 DATA AH4,DRIY4MM The tracks from the microKorg were used as they were recorded. No additional processing was done with Audacity on the PC. The ATR contained in the zip file is a single density 2.5 DOS disk. The Autorun file is SAM . The disk also contains a test program(VOCODER.BAS) used to let SAM speak the words without the timing. This was used when experimenting with the voice programing on the KORG. The MUS file is for use with the MIDI MUSIC SYSTEM. SAMROW.zip These photos were taken to remind future me of the setup before I got organized.
  15. Sorry, I missed the post suggesting floating point routines.
  • Create New...