Jump to content


+AtariAge Subscriber
  • Content Count

  • Joined

  • Last visited

Community Reputation

115 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
    Voice Master
    MIDI Music System
    Diamond GOS - MAC/65
  • Playing Next
    Wii Guitar as Atari game controler

Recent Profile Visitors

13,630 profile views
  1. Using MIDI MUSIC SYSTEM software to build music compositions seems to fit my skill set. I'm not proficient at reading music but I can translate it. My latest arrangement was a Celtic folk song for flute and drums. Music was entered into MMS and a simple drum pattern was added. It sounded terrible. Turns out that a synthesized flute doesn't need to breath and sounds very mechanical without those breaks. Selected notes were shortened and rests were inserted to maintain timing and give the illusion that a breathing person was playing the flute. Sounded much better but it was tedious work. Then I started to think I might have saved a Voice file and used a program to make the changes. Then import the voice back into MMS. Then it dawned on me that I was going to have to figure out the file structure of a voice file and what the data means. At this time I want to share what I think I know about how to create a voice file to import into MMS. Then someday someone (or myself) might write a useful program to create those files. File header and data structure: First thing that was done was to take a look at what a voice data file contained. A few notes were entered in a voice and then the voice was saved. This short program was written to list the content to the screen. Simply change the filename to match the one you wish to view. Use the cntl-1 key to stop and start scrolling. 10 TRAP 100:COUNT=0 20 OPEN #1,4,0,"D:TEMP.V01" 30 GET #1,A:? A;" "; 33 GET #1,A:? A 37 FOR X=1 TO 3 40 GET #1,A 45 COUNT=COUNT+1 50 ? (A), 56 NEXT X 60 ? :GOTO 37 100 ? "COUNT=";:? COUNT This short voice file listing demonstrates the format of the voice file. You may want to build your own voice files and check the results. 24,0 250,0,0 10,48,0 85,48,0 75,48,0 87,48,0 250,0,0 165,48,0 245,51,255 COUNT= 24 It became apparent that the first two bytes will be the number of instructions in the file. LSB - MSB format. Then the instructions are listed. At the end of the a count of the instruction sets is displayed. This should match the 16 bit number at the beginning of the file. An instruction consists of three numbers. The first designates the specific instruction and the next 2 are for any required data. I am assuming that if the data byte is not required by the instruction then MMS does not clear them to zero. That's the only explanation I have for some of numbers I have seen. The first instruction will always be a measure marker(250). Every voice has a measure marker at the beginning. Check it out. Rests and Notes Rest Rn - 0,LSB,MSB n=0 - 65535 cycles In MMS the duration of the rest is its clock value. In MMS you would most likely assign a clock value as W,H,Q,E,S, T, or Z. Their clock values are listed on page 22 of the manual. The "." and " .. " are used to adjust the number of cycles required for the additional durations. There is also the option of setting the duration by entering the clock value as ^n. Keep in mind that meter will determine the clock value in a measure and to keep all the voices synced the total clock value must remain the same for all measures in a composition. (But you don't have to.) Note instructions are between 1 (C1) and 108(G9). If a tie is used bit 7 will be set making the value above 128. To calculate: MMS note number = (MIDI note number - 23) + (128 * IF tie) The duration is set by the next two numbers much the same as for rests. The Table The rest of the instructions are to manipulate the MMS music settings or MIDI instrument. For more information check the manual. If I missed any I'll add the information if I ever find a need to use them. If the Second or Third number's has not been determined then ND has been placed in the table. In fact, it may not have a purpose. Function MMS Input Byte 1 Byte 2 Byte 3 Rest Rn 0 LSB MSB Note (C1-G9)n MIDI# 24-127 MIDI#-23 (+128 if tie) LSB MSB Tempo Tn 240 35-290 ND Sound Sn 241 0-127 ND Program (CC) Pn,x 242 Controller number Setting 0-127 Repeat REPn 243 0 = forever 1-255 ND End Repeat ENDR 244 ND ND Jump to Voice JMPn 245 1-99 ND RETURN RTN 246 ND ND Change Channel /CHn 247 1-16 ND Transpose UP TRUn 248 0-127 ND Transpose Down TRDn 248 Start +256 - n LSB * ND Transpose Zero TRZ 249 ND ND Measure Marker M 250 ND ND Tempo up TUn 251 0-127 ND Tempo down TDn 251 Start +256 -n LSB * ND Pitch Wheel High PWHn 253 ND ND Pitch Wheel Low PWLn 253 ND ND Pitch Wheel Zero PWZ 253 0 ND *= I Think ND = not determined I hope this is a good start to understanding voice files. There are going to be some revisions to this table if I find a need to write a program that will import and export MIDI MUSIC SYSTEM Voice files. That may happen If I find that the M: device driver for the MIDIMax will work with Diamond GOS. I'll incorporate the changes when they are brought to my attention.
  2. Atari 800 user - Compared to now, I guess I was a kid at 30. BASIC was my most used game cart. One puzzle to solve after another. Still haven't figured out all the rules.
  3. I'm thinking about writing some programs to help create MIDI Music System voice files. I've started to decode some of the files and found 5 header bytes then three bytes for each note. There is a lot more to figure out. I can tell this is going to take me some time and wonder if someone might have done this already or know where the information is. I've just started on this quest. I may find some information in the AMS to MMS converter programs or maybe the source code for MMS is out there.
  4. You will want configure your system to avoid using the mouse controller in the Diamond cart. The software is in post #57 and mentioned in the manual. Several programs can't determine if you want to move the cursor or mouse and will crash trying. I have posted most of the software I have written for the Diamond GOS in the blog "Diamond in the Rough". I found an old file on how to turn a CX22 trackball into a mouse and took some photos during the process. Couple of games, an RPN Calculator and some accessories. A couple I put out as shareware they are now in the public domain. Have fun with Diamond GOS.
  5. Post #55 in this thread has the rom and links to the manual and programmers guide
  6. Looks like you can modified the sounds on a MIDIPlus miniEngine USB using control change codes. I might have known that if it had come with a decent MIDI Implementation Chart. I had it hooked up to a MIDI keyboard controller. Playing scales got boring so I reached for the sliders. The results were unexpected. I know that- 1. Changes to the voice are made to the channel. Changes are not reset when you change to a different instrument. Playing the sounds on a different channels will play with factory settings until changed on that channel. 2. Powering down will reset to factory defaults. (Or I haven't found a way to screw up the unit's memory.) These are some of the cc # that I have tried. ADSR 1 - 73, 75, 79, 72 ADSR 2 - 80, 81, 82, 83 ?????? 71, 74, 76, 77, 93, 18 ,19, 16,17, 85 This disk image has a MIDI music system file that will play a few notes, instrument #106, on channel 1, adjust the controls and play again, then switch to channel 2 to play #106 with factory settings. Different sound numbers then used to You will need a miniEngine, MIDI MAX compatable interface, and MIDI Music System V1.0 to hear. ( not sure what will happen when the control codes are sent to a different synthisizer.) ENGTEST1.atr I would sure like to know if there is any more information about this and or if anyone else has any interest in this information. Couldn't find anything on youTube. Would a sound editor for the Atari 8bit be of any use?
  7. If you typed in your first BASIC "HELLO" program and made some small modification then there's a chance you've been typing ever since. I've had some time on my hands and read an old tutorial that begged to be inputted and modified. COMPUTE! September 1983 contains the article "Easy Atari Page Flipping" by Chris Allen. It's a program to demonstrate page flipping on the Atari with plenty of room for experimentation. https://www.atarimagazines.com/compute/issue40/page_flipping.php My first thought was to smoothly move 2 points along 2 different scan lines at different rates with a line between. That was also my last thought but there was very little left of the original program. PLOT and DRAWTO was used on the hidden screen while the other was displayed. Erasing the old line before drawing the new one added some complexity to the program. Not enough complexity to strain ATARI BASIC. The ATR is single density without DOS. It contains the two programs from the article and MYFLIP01.BAS. 198309 Compute 209 page flip.atr If you so choose, start with Chris's program or modify mine in a new direction. Post it in the comment section. Its just something to do if your locked indoors.
  8. Teenage Engineering's PO-33 K.O! is an 8bit sampler. If you don't own an 8-bit computer, this statement might seem a bit restrictive but it can handle sampling much more then just 8 bit sound sources. A YouTube search of "PO-33 KO" can provide a plethora of videos on the subject. I've had mine for a few months and am just now finding the free time to play with it. The video is a first attempt at a loop using samples from the Atari 130XE. The MP3 is the same set of patterns looped 6 times. atari8ko33 loop01.mp3 You may recognize where some of the samples are from. You may also want to see how many you can recognize before you read on. ************************************************************* It was easier for me to record sounds from the Atari using a Digital Audio Workstation(DAW) and then trimming and splicing the samples before recording into the PO-33. The first to be recorded was the drum set. The program "Drum Synthesizer" from Antic Feb. 1985 provided the drum samples. The drums were recorded then assembled into one track. The PO33 recorded the drums and splits the track for playback. The breaks can be adjusted but PO33 seemed to work well enough. The first two melodic sounds were recorded from the program "Musical Atari Keyboard", Antic August 1983. This keyboard has the option of defining a decay rate for the note. Sound 1 and 2 were recorded with decay rates of 0.8 and 0.5. The rest of the 6 sounds were produced from recorded tracks of Star Raider, Missile Command, Frogger, Pac-man, and Q*bert. Recording a quick play of the first level provided a number of familiar sounds. Again, I found that selecting short sections of sound on the tracks and recording on the PO33 and was easier then trimming them on the PO33. Once the sounds were in the PO33, it was just a matter of creating a couple of catchy patterns and recording the loop back into the DAW.
  9. 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.
  10. Good read. Wish I had the money 40 years ago. Now I wish I had the time.
  11. 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…………..
  12. 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.
  13. 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.
  14. 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.
  • Create New...