Jump to content

k-Pack

+AtariAge Subscriber
  • Content Count

    239
  • Joined

  • Last visited

Everything posted by k-Pack

  1. The Diamond Cart is a 64k rom, much like the SpartaDOS X version. There's a lot of bank switching going on. The Disk version was a simple demo disk. More for marketing then use. The Diamond OS 2.0 was the working program. Diamond OS 3.0 added function calls for FILESELECT and MESSAGEBOX. Make a call to one of these and the program will not run in version 2.0. I have used the MAC65-MACROS for these functions(most of the time) to make them backward compatable. There are so few version 3.0s in the world. A copy of the 3.0 rom can be found on page 3 in this message. Also the "Diamond in the Rough" blog may be of interest.
  2. Good read. Wish I had the money 40 years ago. Now I wish I had the time.
  3. There were several issues left unresolved while programing the MIDI IN interface for the ATARI8 joystick ports. The first was to revert back to using the Cassette Motor Control pin on the SIO port for data flow control. This was accomplished with the AU2PORTA shield design. The second consideration was the startup default joystick pin status. The joystick pins are set to high on startup and then grounded to zero by the joystick switches. There is some reverse logic in all of this that still gives me headaches. An Arduino pin set HIGH will turn on the optocoupler transistor and grounds the Atari Joystick pin resulting in a LOW logic level. The Arduino was programed to set all the joystick direction pins to HIGH at startup. PORTA contained 0. The Arduino inverted the MIDI data, thus the Atari was able to read the MIDI note number directly. This could be made to work but here is where the problem lies…….. I wanted to us an ATARIMAX cartridge to hold the programs to be used to produce the sounds. Read MIDI note number from PORTA (joystick port 1 and 2) and use it as index into the tone tables. The problem lay in the fact that the ATARIMAX menu expected to see the joystick working normally but the Arduino was setting all the pins to ground, thus confusing the ATARIMAX. The problem was temporarily solved by unplugging the Arduino before starting/or restarting the computer. A better solution was required. The solution was to start with all Arduino data pins set LOW, when the Arduino was started or reset. The curser keys on the Atari could be used to select the menu program and space bar would run it. Then the Arduino would read the MIDI note number and set pins according to bits. The Atari would read PORTA as the inverted number. The Atari then used an EOR #255 command to invert it a second time and then use that number as an index into the frequency table. This works as long as the MIDI instrument has not send data to the Arduino before turning on the Atari. A MIDI data byte to be sent to the Atari will set the data pins and the trigger, again confusing the AtariMax menu. Press the Arduino reset to clear the serial data buffer and reset the pin logic before restarting the Atari. At least nothing has to be unplugged. Arduino UNO compatible - AU2PORTA shield - MIDI shield These are the test programs for the Arduino and Atari used to troubleshoot the data transfer. The Arduino reads the MIDI data stream and picks out a channel 1 note on or note off command. It then sends a note number to the Atari; where it is used to turn on the note or turn it off. .ATR contains the M65 source Code and related files. READBYTE.atr .ZIP of the Arduino sketch. Atari_Monosynth_AU2PORTA.zip I think I'm at a good place to decide on my next project. I don't think I will go beyond a mono instrument. Some day I may retry shaping the sound using ADSR envelopes and combine 2 - 16bit tones for some kind of harmonic distortion. Or…………..
  4. There I was, in garage sale heaven. Standing over a box of second hand XBOX controllers. I got a little less excited when I noted how second hand they were. I thought I would salvage parts and asked, "How much?". She said, "$2". I said, "OK." He looked like he just lost an old friend and his wife was telling herself, "I should have said 3!" Fast forward 16 months and I'm sorting them into a box labeled "electronic recycle" because I was to lazy to open them up for salvage. One did catch my eye, it was an undersize wireless controller that made me think, "Can the d-pad and a trigger button be wired to plug into my Atari?" Fast forward another couple of months and I'm playing Star Raiders with an XBOX Controller. At least one got saved from the landfill. -------------------------------------------------------------------- These photos were taken for reference. 1 - The controller was a 2.4 Ghz wireless MadCatz. (Receiver not avalible.) 2 - The main board after removing the transmitter and battery holder. 3 - Removed 2 screws and lifted the D-pad. 4 - Cut off existing wires. 5 - Solder wire for up, down, left, right, and Ground (common). Note wire colors, mine not standard. 6 - Contacts in placed and wires routed. One of the cross pieces in the plastic bracket needed to be remove for the board to sit flat. Solder joint interference. 7 - Cut a notch in case for CX40 cable. 8 - Solder 2 wires for trigger switch. One for the trigger pin and one for the ground. (solder joints are for a different design that didn't work so well. They didn't need to be moved.) 9 - Clean off resistive material across B contacts and solder micro switch as close to center as you can. Be sure the plunger will make contact with button. (the wires could have been soldered to the push button switch and glued into place.) 10 - Solder leads to joystick cable. UP-Pin1, Down - Pin2, Left - Pin3, Right - Pin4, Trigger - Pin6, and other side of trigger and common on d-pad - Pin8. 11 - Because the push button was to high, the plunger needed to sanded shorter. 12 - On the upper case, the button guide required some material removal to keep from depressing the switch. 13 - Put the case together. Be sure wires are not pinched or interfering with button movements. The case was opened and closed several times to make modification before the trigger reliably worked. I was really close to giving up. There was a bit of lucky with the d-pad. This joystick tester came in handy. I think it saved me more time then it took to build it.
  5. Back in January of 2015, I wanted of use a PING)) ultrasonic sensor to measure distance and send it to the Atari using the 850 - RS232 ports. I initially thought that I could move my hand in front of the sensor and the resulting change in desistance could be used to change the frequency of the sound command. This might have worked if the SIO port could be used to make sound .AND. transmit data to the 850 interface at the same time. It doesn't. So, I forgot about the sound and just got the distance data to the Atari and wrote up the blog entry. Now that the Arduino Uno to PORTA shield (AU2PORTA) is at my disposal, I can bypass the SIO port and receive the data through the Joystick ports to control the sound frequency. The Arduino reads the sensor data, scales it from 0 to 255, and sets the joystick pins. The Atari simply PEEKs the memory for PORTA and sets the SOUND command. -------------------------------------------------------- Hardware setup - Plug the AU2PORTA shield into the Arduino UNO. Connect the PING)) sensor to the Shield. PING)) ------- Arduino GND GND 5V 5V SIG D2 Plug the AU2PORTA joystick cables into the correct Atari joystick port. Arduino UNO program - /* This Arduino program receives data from a PING))sensor. Then scales the reading to an 8 bit number. That number is send to the Atari Joystick ports using the AU2PORTA shield. Pitch data is also sent to the Arduino IDE serial monitor for troubleshooting. PING))code example used to read sensor (Examples/06.Sensors/Ping) Kevin Packard January 2019 */ // Atari PORTA(54016) mapped to pins on arduino int porta0 = 4; int porta1 = 5; int porta2 = 6; int porta3 = 7; int porta4 = 8; int porta5 = 9; int porta6 = 10; int porta7 = 11; int trig1 = 3; const int pingPin = 2; PING)) //sensor data pin byte pitch = 0; byte lastPitch = 0; byte zero = 0; 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,HIGH);} else {digitalWrite(porta0,LOW);} if (byteToMap & B00000010){digitalWrite(porta1,HIGH);} else {digitalWrite(porta1,LOW);} if (byteToMap & B00000100){digitalWrite(porta2,HIGH);} else {digitalWrite(porta2,LOW);} if (byteToMap & B00001000){digitalWrite(porta3,HIGH);} else {digitalWrite(porta3,LOW);} if (byteToMap & B00010000){digitalWrite(porta4,HIGH);} else {digitalWrite(porta4,LOW);} if (byteToMap & B00100000){digitalWrite(porta5,HIGH);} else {digitalWrite(porta5,LOW);} if (byteToMap & B01000000){digitalWrite(porta6,HIGH);} else {digitalWrite(porta6,LOW);} if (byteToMap & B10000000){digitalWrite(porta7,HIGH);} else {digitalWrite(porta7,LOW);} } 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(trig1,OUTPUT); setPorta(zero); Serial.begin(9600);// } void loop() { long duration; // from Ping example pinMode(pingPin, OUTPUT); digitalWrite(pingPin, LOW); delayMicroseconds(2); digitalWrite(pingPin, HIGH); delayMicroseconds(5); digitalWrite(pingPin, LOW); pinMode(pingPin, INPUT); duration = pulseIn(pingPin, HIGH); // if(duration < 200 || duration >3500){duration = 200;} // duration 200 us note off pitch = map(duration,200,3500,0,255); // Scale duration for Atari pitch setting if(pitch != lastPitch){ // look for pitch change from last setting digitalWrite(trig1,HIGH); // let atari know not to read pitch while port is being set setPorta(pitch); // set pins with pitch data digitalWrite(trig1,LOW); // let atari know data ok to read lastPitch = pitch; // store latest pitch Serial.print(pitch); // display pitch in Serial Monitor window(if connected) Serial.println(); } delay(100); // delay for PING)) and atari to sync. }// End of Listing Atari BASIC code example - 100 IF STRIG(0)=0 THEN 100 200 PITCH=PEEK(54016) 210 IF PITCH=255 THEN VOLUME=0 220 IF PITCH<>255 THEN VOLUME=10 300 IF PITCH=LASTPITCH THEN 100 400 SOUND 0,PITCH,10,VOLUME 500 LASTPITCH=PITCH 510 ? PITCH 600 GOTO 100 While the programs are running, you should be able to move your hand (or other sound reflective object) closer and further from the PING)) sensor to hear a change in pitch.
  6. Over the years I've been using an Arduino UNO to setup data for transfer to the Atari Joystick ports. The first attempt was to read the data from a Wii nunchuk and translate it to joystick movements. Lately I've been experimenting reading midi data using an Arduino Midi Shield, along with using the Cassette Motor Control pin on the SIO port as feedback to the Arduino. You may have read some of these blogs. During the "Switched On POKEY" music experiments, there were many modifications tried and some were put off for later evaluation. At first the cassette motor control(CMC) pin on the SIO was used to signal the Arduino. Then bit 7 of PORTA(joystick) was set as output and trigger 2 was set and used for bit 7 input. It worked but didn't solve a click problem I thought I was having when switching the CMC. MIDI setup then and now: It seemed time to gather my thoughts and solder together a prototype shield. And to, establish a point of reference for beginning future experiments. From now on I will refer to this Arduino Uno shield as AU2PORTA. This shield will be able to set the joystick direction pins (PORTA) and the 2 triggers. With 1 bit output from the Atari's CMC pin, wired to be used to signal the Arduino when needed. The parallel data transfer used most of the digital lines. D0 and D1 are used for serial communication with the MIDI shield (or computer) leaving D2 free for other uses. The Analog signal lines are still avalible for analog input, I2C devices or reading voltages of digital logic signals. The ground for each of the joysticks are separate. This allows the shield to be hooked up to a joystick port of different computers and maintain separate grounds. This might come in handy someday. The circuits use 11 optocouplers (PS2501). Some people may think I am being overprotective of my Atari computers but I prefer to think of it as being very protective of my computers. These isolators will keep the Arduino and Atari circuits from harming each other, no matter what gets hooked up to the Arduino. Note: The prototype circuit uses the PS2501 for CMC feedback bit and worked. I grabbed a PS2502-1 optocoupler from the parts bin while building the shield. The PS2501 has one transistor while the PS2502 has two in a Darlington configuration. They both work. The next shield that gets built will use a PS2501-1. The shield was soldered and tested using the following Arduino program that set all the digital pins HI and then LOW. *The Arduino toggles the pins wired for the Atari to read. * *The CMC circuit is not tested. * */ // Atari PORTA(54016) mapped to pins on Arduino int porta0 = 4; int porta1 = 5; int porta2 = 6; int porta3 = 7; int porta4 = 8; int porta5 = 9; int porta6 = 10; int porta7 = 11; int trig1 = 3; int trig2 = 12; int digPin=0; 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(trig1,OUTPUT); pinMode(trig2,OUTPUT); } void loop() { for (digPin = 3; digPin<13; digPin++) { digitalWrite(digPin,HIGH); } delay(200); for(digPin = 3; digPin<13; digPin++) { digitalWrite(digPin,LOW); } delay(200); } Then when the Arduino and Shield are hooked up to the joystick ports this next small Atari BASIC program was used to read the trigger and joystick. 15 means all Arduino controlled digital pins are LOW. 0 for all HIGH. Triggers; Arduino is HIGH and Atari reads 0.(Note the reverse logic. Arduino - LOW/Atari - HIGH. Very important when programing) 10 ? STICK(0),STRIG(0),STICK(1),STRIG(1):LAST = STRIG (0) 20 IF STRIG(0)=LAST THEN 20 30 GOTO 10 Once the 3 bad solder connections were fixed, the following program was used to toggle the Cassette Motor control on the SIO port. A Volt meter was used to read the voltage drop across the 1K resistor as it was switched. Atari HIGH - Arduino HIGH. 10 POKE 54018,52:REM TURN ON CMC 20 FOR X=1 TO 200:NEXT X 30 POKE 54018,60:REM TURN OFF CMC 40 FOR X=1 TO 200: NEXT X 50 GOTO 10 The next task is to optimize the data transfer routines and resolve problems that are caused by the reverse pin logic and the startup logic defaults.
  7. I think the last time this happened to me, my dad pulled the tubes and we drove to the drug store to test them. This might be of help if I could remember which tube it was.
  8. k-Pack

    Classic music

    Ever wonder what they would do with today's equipment?
  9. My Catch-22: If I knew what I know now, I am not sure I would have started this project. But If I didn't start this project, I would not have learned what I know now. It seems like it has taken forever to finish the tracks but I'm not sure when it started. In October 2018 the prologue was written; that's only 10 months. If you consider I started experimenting with programing MIDI, it started when "Computer Blues" was modified to output midi commands through the 850's RS232 port; September 2016. I would expect that it took about 2 months of work from track one to twelve, if you only consider when inspiration and motivation were at sufficient levels to advance the project. Much thought was put into deciding if some of the tracks should be redone (they are not all my favorites). There is still a lot that can be done to the Arduino interface. The Atari Software could use a few more options. These changes will come in the future. Today, I am even more amazed at what Wendy Carlos was able to accomplish in 1968 to produce Switched On Bach. Just the fact that I didn't have to deal with the Atari detuning half way through recordings and the free multi track recording software is so much easier to use then tape; the lack of which would have stopped me in her tracks. ------------------------------------- Rough draft for the cd jewel case insert. SOP Jewl case draft.pdf
  10. If you don't need a keyboard and just want to play/arrange some midi songs there is the MIDIPLUS miniEngine USB. The sounds are fixed but they are the standard midi instruments. I use it when I'm entering notes into MIDI MUSIC System and don't want to get out the heavy equipment for playback. It's about $65 US. Not sure how hard it would be to get one in Belgium.
  11. Since the Switched On Bach album was released in 1968 and the Atari 800 was introduced in 1979, it seemed fitting that I would should start with the 1979 Atari and fade into the 1990 Yamaha TG-33. Brandonburg #3 third move.mp3 NOTES: Music File origin: Sheet Music VBURGM3.MUS for Atari RECORD.MUS for TG-33 RECORD.INF for TG-33 channel assignments Control Computer: 130XE Sequencer Software: MIDI Music System by Lee Actor Voice 1 - PAT9 Voice 2 - PAT10 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 each voice settings) (.Included READMIDC.M65) - PAT8.OBJ PAT9.OBJ PAT10.OBJ Loaded from ATARIMAX Cart. Yamaha TG-33 Sound Card VC3303 - Voice Data Card Multi C1-15 CLASSIC Voice 1 = Channel 5 Voice 2 = Channel 5 Voice 4 = Channel 4 Mixer: Behringer Xenyx 1202 FX Mic One input - Atari monitor port LINE IN 5/6 - Yamaha TG-33 FX : #3 MID HALL 1 Recorder: PC - Audacity 2.1.2 File: Brandonburg #3 third move.aup - Sync tracks and trim - Fade in and out TRACK12.atr
  12. Bach had the idea to write the second movement as 2 cords in one measure. Some believe that it was a place holder and Bach was going to finish the second movement at a later date and others say it provided a musician a starting point for improvisation. Wendy Carlos created a track that had me thinking her efforts were directly influenced by Bach's spirit. I'm not so lucky (or maybe your not so lucky). I took the notes of the cords and arranged them in sequence to produce the following. I'm not sure Bach would have approved of the somewhat haunting melody the sequence produced. Brandenburg No3 second movement.mp3 NOTES: Music File origin: IMPROV01.MUS - k-Pack Control Computer: 130XE Sequencer Software: MIDI Music System by Lee Actor Voice 1 - PAT8 Voice 2 - PAT6 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 each voice settings) (.Included READMIDC.M65) - PAT6.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 Second Movement.aup - Sync tracks and trim TRACK11.atr
  13. 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
  14. 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.
  15. 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.
  16. 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.
  17. 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
  18. 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
  19. 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
  20. 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
  21. I'm pretty sure that pokey is used as a clock for the sio. Can't be used for both at the same time.
  22. 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.
  23. Once I see c it's hard to unsee it.
  24. 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
  25. 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.
×
×
  • Create New...