/S06::$d400::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: An inside look at MODplay 128 +-+ by +-+ Nate Dannenberg and Mike Gordillo Nate Dannenberg is an expert at digitizing sounds on the Commodore 64 and 128. For the past year or so, he has been the heart and soul of probably the most revolutionary program in Commodore 64/128 audio since Mark Dickenson's Stereo Sid Player. MODplay is the name and it will rock your system to the core. You are the first priviledged readers to get a sneak peek at this exciting bit of software. -- > Nate, you are the author of the world's first and only .mod player on the > 8 bit Commodores. I am curious to explore some of its inner workings. > > But first... What exactly IS a "mod" anyways? Mike, you probably know the answer to that one already. A mod is simply a music file format which started on the Amiga line of computers and spread to many other systems. It is a very efficient format in which music is sampled or cut into discrete portions and later reassembled in many different ways to create varied tunes and patterns to form a musical score. The module format can be summed up as a form of musical archive. A few instruments may be sampled only once, but their samples can be manipulated in thousands of ways that may not be possible on the actual instruments. For example, a sample of a flute can form an entire orchestral piece in and of itself without much effort. However, in order to achieve this, a computer requires a moderate amount of speed and memory. Many have discounted the possibility of .mod playback on our machines and have therefore not explored the true limits of hardware in this regard, until now. > The C128 is not known for top speed and memory though. Fortunately, it has just enough speed and memory when combined with a 17xx Ram Expansion Unit (REU). To be perfectly honest, my modplayer can only function with an "REU" and a C128 running at 2 MHz. But it functions well enough to keep tempo with the majority (if not all) the 4 track "mods" out there and it can even output sound in 8 bits! In the future I may try to support the Ramlink/Ramdrive units and perhaps one or two of the more popular internal ram (256k to 1 megabyte) expansions. Although the Ramlink/Ramdrive units may not have enough speed for the task, I do believe the CMD Super 64 and 128 accelerators will change this and allow for potentially both C64 and C128 accelerated modplayers in the future. > But for many years, I have heard (from Amiga users primarily) that our little > machines did not have the CPU horsepower necessary to simultaneously process > and play back the module format. Amiga users cannot be wrong! How did you > manage to do it? You have to know a little about how the module format works, but without going into too much detail, imagine all samples within a .mod file as being organized into rows and patterns. These rows and patterns determine what, when, and how sample data gets played back to the user. In my player, rows and patterns are centered around their respective tracks (channels). The basic procedure is described as follows : Get the 16 byte row data from the ram expansion unit. Now divide the row into four 4-byte subsections where each subsection represents a track (1,2,3,4). Get the current 1 KB pattern data into memory and extract the next 16 byte stub from that pattern. Divide the pattern stub as the row was divided before (into four 4-byte subsections) to match each track. Within each four byte track, pattern information about a row is divided into a sample number, a note period, an effect command, and an effect parameter. The sample number directs the program to use a certain sample for whatever row (i.e., notes) are being played in that track. The sample number is derived as follows : "zeroth" high nybble byte + (second high nybble byte/16). It is then used to index a data table where info such as sample length and start address inside the ram expansion unit are obtained. The note period, on the other hand, tells the CPU how many 3.5 MHz ticks to count down before sending out the next sample byte. The note period is then used as a lookup into a frequency stepper table in order to determine the pitch of the note. A value of 254 for example would be the equivalent of concert pitch A-4. The effect command modifies the pitch, playback time of the note or the whole pattern, and the volume if needed. You can use it to apply an array of effects to each note, including vibrato, portamento, arpeggio, etc. The effect parameter in turn modifies the effect command. For example, if the effect command is a zero and its parameter is a zero as well, then any effect for that track will be cancelled immediately. Likewise, if the effect command is zero and its parameter is something other than zero, then the effect command is treated as an arppegio using the supplied parameter value. For reference, if any pattern value for a given row is zero then the pattern data for the previous row is used. After all is said and done, my program grabs all the module data in little spurts from the ram expansion unit at approximately 459,200 bytes per second leading to (after processing) an effective 8.2 KHz play-back rate. It is interesting to note that my modplayer could reach nearly twice the sample rate it has now if it were to pull its data from the 128's internal memory. Alas, there are few .mod files that could comfortably fit in 128 kilobytes. If I decide to allow the player to grab data from internal memory, it would probably be in support only for internal ram expansions. > How would internal ram be faster as compared to the ram expansion unit? The ram expansion unit (REU) is a marvelous blessing. It allows my program to naturally store huge .mod files and has the fastest transfer rates of any ram storage device in the Commodore 8 bit market. Despite this, it does carry overhead penalties that simply do not exist when accesing internal memory. For example, I must calculate a three-byte value into the ram expansion unit (LSB, MSB, RamBank) and copy it to the ram expansion address pointer and also into internal memory. I have to toggle down to 1 MHz while accesing the REU. I then toggle back up to 2 MHz while copying the module data into the C128 as I do a 4-level deep interleave on the module data itself. As this entire sequence is repeated many many times, you can see how much time is lost. If I were doing all this from internal memory, I would have to again calculate the three-byte pointer but this time I could keep it in zero page and would never have to copy it anywhere (except to copy the bank pointer to the memory mangement unit inside the C128). I would never have to switch to 1 MHz mode. Furthermore, I would not need to access the module data in small chunks as it would all be easily available in internal memory. As it stands now, data is cached into the C128 as described earlier for logistical reasons concerning ram expansion overhead times. A more direct method of accessing the module data would be simple with internal memory. > You mentioned that your modplayer outputs in 8 bits. Could you explain > how you squeezed 8 bit audio out of the C128. Originally, I used a technique called Pulse Width Modulation to do it. Remember that early 64/128 digiplayers used the $d418 reg. for 4 bit digis. I used $d402 instead as the DAC register while toggling the test bit in $d404 for each sample byte. I then filtered voice 1 and WHAM, instant 8-bits. The techinique is interesting and might be of use to you, as follows : Simply put, just set voice 1 to produce a pulse waveform for the current sample rate. This pulse will range from zero to maximum width. At the sample rate of my player, max. width corresponds to 127 cycles. Now start stuffing numbers into $d402. Each time you do that, put a hexadecimal 49 and then 41 into $d404 and be sure to filter voice 1 with a low pass..voila. Your timing needs to be good and steady. Needless to say, the whole operation works best in 2 MHz mode. Using pulse width modulation, the pulses can range from 1 cycle to about 127 cycles wide at the 8.2 KHz sample rate. That is equivalent to 7 bits and the filter gives you a boost in quality (i.e., effective 8 bit resolution). The one major drawback with the PWM technique is that it leaves behind a residual squeal that is audible at the current sample rate. I am currently working on a methodology to completely eliminate the squeal and the most promising option appears to be an extension of the PWM technique known as PCM or Pulse Code Modulation. There is also a minor problem with low volume output but this is easily corrected by amplification at the user's sound system. > These 8 bit techniques you mentioned are for use with the SID chip. Do you > have any other ideas in mind? If the SID had a volume register from 0 to 255, I could have used the standard $d418 DAC technique for 8 bit resolution. As this is not the case, PWM/PCM is necessary for the quality I hope to get out of the SID without resorting to additional hardware. I do provide standard 4 bit and dithered 4 bit sound output in the program and will fully implement 8 bit SID sound when I feel it has met my requirements. However, I have not discounted other options. As seen elsewhere in this first issue of disC=overy, I have gone into detail on an 8 bit DAC board that is very simple to build and program. The modplayer already supports this particular board as a low cost alternative. I am also working on a more advanced dual DAC -- ADC board that will be available for sale along with the modplayer. It will have four tracks, each of 8 bits and with an 8 bit linear volume control yielding an effective 16 bits of resolution per channel :). > Before we depart, I would like you to emphasize the difficulty in what you > have done, a C= 6510/8502 modplayer! :) The task was not terribly difficult in theory. In practice it has sometimes become quite a hassle and it is still in progress. If you want a comparison, for a no-frills .raw digi format (not the module format) you could probably get away with over 80 (eighty) KHz in simple 4 bit mono on a C128 at 2 Mhz and you can do about 60KHz 4 bit mono from the ram expansion unit. On a C64 you should be able to do at least 30 KHz mono 4 bits from the ram expansion and about 44 KHz from memory. Obviously, these would be short samples but the drive home point is that the module format is indeed a computation-intensive exercise when compared to .raw digis. Regardless, my player can handle up to 31 samples, up to 255 patterns, 4 to 8 bits, 4 tracks, and up to two megabytes of .mod file if you have the 2 meg REU expansion. I have not yet implemented the sliding routines yet, and its sample rate of 8.2 KHz, although not exceedingly high, is quite adequate for many .mod files. I do believe that the new SuperCPU 64 and 128 accelerators from CMD will allow for even greater sample rates and generally make my task easier overall. I will take a close look at them and at internal memory expansions. If I find these "vehicles" to be proper and good, I may support them in the modplayer. > I'd like to thank you for granting this interview, Nate. Well, just don't let it go to your head, Mike. :) > ;) -- For more information on this one of a kind product, you may reach Nate at the following addresses: Dannenberg Concepts, Ltd. "Bringing your Commodore 128 one step closer!" Email: tron@wichita.fn.net Phone: (316) 777-0248 Snail: Dannenberg Concepts, Ltd. c/o Mr. Nate Dannenberg 306 S. 1st Ave Mulvane, KS 67110 FidoNet: 1:291/25 Groups: CBM, CBM-128, and CBM-GEOS Usenet: comp.sys.cbm, alt.binaries.sounds.mods /S07::$d600::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Some preliminary data on VDC timing by SLJ 1995/96 (comments -> sjudd@nwu.edu) ----------------------------------- With some very helpful commentary from Andreas Boose! The 80-column VDC chip on the C128 is one of the least documented features of the 128. All documentation I have found echoes the 128 PRG, so that the general features and programming of the chip is well known, but as far as I can tell there is zero information on timing, internal operation of the VDC, etc. In an attempt to gain some insight into the timing and operation of the VDC I wrote a series of simple experiments. Later I received some helpful suggestions and comments from Andreas Boose: any comments indented with a '>' are from him. My personal interest is in using the VDC as a graphics coprocessor. As anyone who has programmed the VDC knows, all communication with the VDC is done through two memory locations, $D600 and $D601, and entails the use of a busy-loop to determine when the VDC is ready to be read or written to. My idea was to have the 8502 doing something useful instead of sitting around waiting for the VDC, so that I could for instance do some calculations while the screen is being cleared. Attached are some simple programs I wrote to get a feel for VDC timing. There is an ML program to do the VDC operations, and a BASIC program to generate a little statistical analysis of data. Eight tests are performed and timed using CIA #2 timer A. In retrospect some are pretty naive, but I include them all for the sake of completeness: Test 1: This is a simple calibration test to determine how many cycles are used in starting/stopping the timer. It simply starts the timer, executes 5 NOP instructions, and stops the timer. By subtracting 10 cycles from the time elapsed, you get the overhead. Test 2: Load a register (Reg 18) -- This test simply times how long it takes to tell the VDC which register you want to operate on -- no reads or writes are performed. The idea is to calculate how long it takes the VDC to find a register. Note that the register is not loaded with anything -- by "loading a register" I simply mean making it read/write accessible. Test 3: Load a single register twice. My idea here was to see how 'smart' the VDC was, i.e. if it already had the register loaded, would it spend any extra time reloading it. In principle this should be twice Test 2 above. Test 4: Load all registers. This test starts at register 36 and goes down to zero. The idea here is to see if different registers take different amounts of time to fetch, i.e. will we just get 37 * Test 2 here? Test 5: Two reads of register 18. The whole point of this test is to see if _reading_ from a loaded VDC register affects subsequent loads in any way (the expectation is that it would not). In principle this test should be Test 3 plus an additional 8 cycles for the 2 LDA's. Test 6: Read a single VDC memory location ($1919). This is a test to see how long it takes to find and read a memory location within the VDC RAM. Location $1919 was used simply because the value $19 was already in the accumulator :). This one should take a little more time than three register accesses. Test 7: Loop memory fill. Using a loop on the 8502 side, this test fills 256 bytes of VDC memory, starting at location 0, using the auto-increment feature of the VDC. Test 8: Block memory fill. This test uses the block-write feature of the VDC to fill 256 bytes of VDC memory (0-255). Naturally the idea is to compare it to Test 7. Just to make sure the test 7 was doing what I wanted it to do I stored the VDC memory location after the loop, to make sure it was $0100 (which it was :). The BASIC program runs these tests a bunch of times (parameter N in the program) and calculates a few averages. The data is all stored in arrays so that it can be viewed, sorted, or whatever. The first time I ran these experiments I did so in SLOW mode and in FAST mode. In slow mode an extra 43 cycles would pop up from time to time. As several people informed me, >This has not anything to do with interrupts, it's the VIC-IIe's DMA which >halts the 8502 on any bad-line for 40-43 cycles. To avoid this jitter >switch off the screen before measuring, lda#$0b:sta$d011:lda$d012:bne*-3. >Note the loop after switching the screen off. It's important to wait until >the raster counter is out of the text area as switching off the screen >doesn't affect the current screen. After measuring you can switch on the >screen with lda#$1b:sta$d011. These extra cycles disappear in 2MHz mode, however: >Yes, switching to 2MHz forces the VIC-IIe to leave the phi1/2 DMA cycles >(almost) untouched. This is a very brutal way to get rid of the 40-43 DMA >cycles since the VIC's core doesn't know that you want him to leave these >cycles untouched until you have switched off the screen. So it still tries >to perform DMA. As this would mean a bus collision with the 8502 a >protection circuit inside the VIC shuts down its address lines, AEC and BA >on DMA times. The VIC never gets the data it wanted to display a picture, >it gets the data the 8502 has accessed - this gives are real bogus screen. >:-) As a comparison, two runs follow; the second run is in SLOW mode, with VIC turned off, and the first is in FAST mode. Both runs do 120 repetitions (N=120): FAST mode, N=120: Test 1: Overhead = 1.4 (expected=1.5) Test 2: Single register = 4.9 (expected=5) Test 3: Single reg twice = 10.14166... (expected= 9.8) Test 4: total time= 304.166... minus loop overhead= 212.166... div 37 BIT-loops = 27.166... => bit-loop repetions = 7.7619 Test 5: Two reads REG 18 = 14.36 Expected = 13.8 (twice Test 2) Test 6: One memory fetch = 115.66... Expected = 20.7 diff = 94.966... Probable waits for VDC Reg 31 fetch = 27.133... Test 7: Loop memory fill= 10755.766... Extra VDC waits= 8347.866... Avg BIT-loop repetitions = 9.3168 Test 8: Total block fill= 179.94166... => Approx VDC time spent on 256 byte block fill= 153.24166... I include the above just for the sake of comparison; my 'expected' values are very naive, and the numbers themselves are not terribly insightful. SLOW mode, VIC disabled, N=120: Test 1: Overhead = 3 (expected=3) Test 2: Single register = 10 (expected=10) Test 3: Single reg twice = 20 Test 4: total time= 554 minus loop overhead= 370 div 37 BIT-loops = 0 => bit-loop repetions = 0 Test 5: Two reads REG 18 = 28 Expected = 28 (twice Test 2) Test 6: One memory fetch = 118.766... Expected = 42 diff = 76.766... Probable waits for VDC Reg 31 fetch = 10.966... Test 7: Loop memory fill= 11614.5333 Extra VDC waits= 6747.533... Avg BIT-loop repetitions = 3.76536458 Test 8: Total block fill= 197 => Approx VDC time spent on 256 byte block fill= 143 Comments: Tests six and seven are the only tests which showed variation; all other tests stay constant throughout all trials, with one notable exception: Test #8 weirdness: _Very_ occasionally a spurious number will come up, and always only on the first trial. It is possible to duplicate: from the BASIC program, set N=5 say (so you don't have to wait forever). When the first tests are reported and the program pauses for input, hit run/stop -- the cursor should now be red. Then rerun the program, and watch the last number printed. It will usually be 200, but sometimes numbers such as 1019, 1012, 592, and 963 pop up on the first trial. If you break the program at other places, though, these numbers don't come up. This is a mystery to me. 1MHz mode with VIC turned off is the most reliable indicator of VDC's performance: Test 3 is indeed just twice Test 2, which is not surprising for register 18, since the BIT-loop is never executed. (Twice Test 2? Timid termites tremble, eliciting tempting titilations. Temperance!) Test 4 again suggests that no registers take longer to come up than others. In effect, it doesn't seem to take up any time to set up a register. Test 5 verifies our intuition that reading $D601 doesn't alter timings of subsequent operations. Test 6 is an interesting one. A typical memory fetch takes a fair amount of time! Test 4 tells us that just setting up the register doesn't take any time; it is the write to the registers, which then causes VDC to go and fetch the data, that slows everything down. This will be discussed below. Test 7 shows that memory writes are somewhat time consuming. Test 8 shows that the block-fill is a two order of magnitude improvement over Test 7 though! 143 cycles versus 11000 -- wow! Also of interest is that there were some BIT-loop repetitions; I expected them to not be necessary. Andreas Boose provides a lot of insight into some of the issues raised above: >Stephen, 2MHz mode is not so easy as you might think. There are two facts >you have to take in account: > >#1 In 2MHz mode a single raster line consists of 65 phi1 and 65 phi2 >cycles. But the 8502 doesn't get all cycles! During the last 5 phi1 cycles >of any raster line the VIC-IIe must refresh the system's DRAM and so the >8502 is switched to 1MHz on these cycles. Simply counting the cycles of >the code and dividing them by 2 is not accurate. For a serious measurement >you would have to synchronize the test loop to the VIC-IIe's refresh and >to periodically count 120 cycles @2MHz and then 5 cycles @1MHz. > >#2 In 2MHz mode accessing VIC-IIe, SID, CIAs or $DE00-$DFFF forces the >8502 back into 1MHz mode. But it is not simply done by counting these IO >accesses as 2 2MHz mode cycles: It is different whether the IO access >occurs during phi1 or phi2. If it happens on phi1 the VIC-IIe expands the >cycle into phi2 and we get 2 2MHz cycles. If it hits on phi2 the VIC-IIe >delays the IO request to phi1 and then the 1MHz mode access is performed. >So this consumes 3 2MHz cycles instead the expected 2 cycles. > >For exact measurement 1MHz mode with switched off screen might be the >best reference. But even with accurate 1MHz 8502 you will not get rid of >odd values, the VDC has its own clocking frequency derived from a separate >16MHz source which slides relatively to the 8502's system clock. Therefore >there will be always some 1/2 or 1/4 cycle jitter on any $d6xx access. > >Also for exact measurement you have to align your routine to the VDC >timing. In the moment you rely on the fact that the VDC can execute the >same command in the same time regardless on what the VDC doing on the >screen - but surely that matters. CBM engineers were 2MHz-DRAM-bandwidth- >weenies and the VDC occupies lots of its RAM bandwidth for drawing the >picture and refreshing the DRAM. So it must delay "foreign" RAM access of >the 8502 to certain timing slots like the horizontal or vertical retrace >or so. Clearly, my experiments have just scratched the surface of the VDC. We can make a few conclusions however: - In many cases the usual BIT-loops are unnecessary. The things which seem to make them necessary are the things which can tie VDC up, namely any operations which need to talk to his memory (did I mention that VDC is a 'he'?). - Some operations, such as a fill, are not only efficient but take a consistent amount of time to execute. Others, such as the memory fetch, do not. The VDC strikes me as being 'the final frontier' of the C= world, in that it is not terribly well understood and there is still much to be explored. There are two things which I think would be very nice to have, concerning VDC: first an understanding into the internal operation of the chip, and second a list of timings for various operations involving VDC, with the goal of really utilizing VDC for the graphics coprocessor that he can be. Source + 2 binaries to follow. ------------------------------------------------------------------------- * * vdctimes.s * * The purpose of this program is to gather some timing * information on the VDC chip. It simply uses CIA #1 * timer A to measure the time to perform a series of VDC * operations. A BASIC program will then statistically * assemble the data. * * Stephen Judd * 8/3/95 ORG $1300 TIMALO EQU $DD04 ;Timer A, CIA #2 TIMAHI EQU $DD05 CIACRA EQU $DD0E ;Control register A * Now some macros SETREG MAC ;Set a VDC register STX $D600 L1 BIT $D600 BPL L1 <<< ELAPSE MAC ;Calculate time elapsed SEC LDA #$FF SBC TIMALO STA ]1 LDA #$FF SBC TIMAHI STA ]1+1 <<< SEI INITTIM LDA #$FF ;Stick 65535 into STA TIMALO ;timer latch STA TIMAHI LDA #%00011001 ;Start timer LDY #%00001000 ;Stop timer CALIBRAT STA CIACRA ;Figure out overhead in NOP ;starting/stopping timer NOP NOP NOP NOP ;Elapse 10 cycles STY CIACRA LDA #$FF SEC SBC TIMALO STA TEST * First test: No OP; just load a register REGTEST LDX #18 ;Register 18 LDA #%00011001 STA CIACRA ;Start timer >>> SETREG ;A single reg STY CIACRA >>> ELAPSE,REG1 LDA #%00011001 STA CIACRA >>> SETREG ;Do it twice >>> SETREG STY CIACRA >>> ELAPSE,REG2 LDX #36 ;Now we will do them all LDA #%00011001 STA CIACRA :LOOP >>> SETREG DEX BPL :LOOP ;Sub 5*37-1 cycles from total STY CIACRA >>> ELAPSE,ALLREG READVDC ;Just a quick test to see if LDX #18 ;anything weird happens by a LDA #%00011001 ;read STA CIACRA >>> SETREG LDA $DC01 >>> SETREG LDA $DC01 STY CIACRA >>> ELAPSE,READ18 ;This should be REG2+8 WRITEVDC ;Various tests of writing to LDA #%00011001 ;the VDC STA CIACRA >>> SETREG ;Now read an actual memory STA $D601 ;location INX >>> SETREG ;Three setregs total STA $D601 ;Overhead: 6+6 cycles LDX #31 >>> SETREG STY CIACRA >>> ELAPSE,READ31 LDX #18 ;Now test memory fills LDA #00 >>> SETREG STA $D601 >>> SETREG STA $D601 LDA #%00011001 LDY #00 LDX #31 STA CIACRA LDA #$66 ;Screen code 102 :LOOP >>> SETREG STA $D601 INY BNE :LOOP ;Overhead: 2+2+5*256-1 ;(or 9*256 if sta is counted) LDY #%00001000 STY CIACRA >>> ELAPSE,FILLSLOW LDX #18 LDA #00 >>> SETREG STA $D601 INX >>> SETREG STA $D601 LDA #%00011001 LDX #31 STA CIACRA ;Here we go... LDA #$66 >>> SETREG STA $D601 LDX #24 LDA #%00000000 >>> SETREG STA $D601 LDX #30 LDA #$FF ;Total of 256 writes >>> SETREG STA $D601 ;Off it goes! LDX #18 >>> SETREG ;Hopefully this will wait until STY CIACRA ;the fill is done! LDA $D601 ;Just to make sure, check the STA MEMADDR ;last address written to INX >>> SETREG LDA $D601 STA MEMADDR+1 >>> ELAPSE,FILLFAST CLI RTS ;Whew! TEST DS 1 ;Calibration test REG1 DS 2 ;Single register test REG2 DS 2 ;Same register twice ALLREG DS 2 ;All 37 registers READ18 DS 2 ;Two reads of register 18 READ31 DS 2 ;Three reads minus 12 cyceles FILLSLOW DS 2 ;256 writes MEMADDR DS 2 ;lo/hi of memory fill (a check) FILLFAST DS 2 ;One block write of 256 chars -- begin 644 time1.0f.uu M 1P7' $ F2 BFY-0051)14Y#12XN+B( )1P" $ZR,3(P.D.R, !6' , _B8Z M1K(Q.I<@-3,R-C4LPB@U,S(V-2D@KR R,SDZCR!455).($]&1B!624, 91P$ M (\@1D%35#I&/3( H1P% (8@5#$H3BDL5#(H3BDL5#,H3BDL5#0H3BDL5#4H M3BDL5#8H3BDL5#J?^. -8L -80^XT! MUJ(2C@#6+ #6$/N,#MVM =:-UA3HC@#6+ #6$/NM =:-UQ0XJ?_M!-V-V!2I M_^T%W8W9%%A@ :&AH:&AH:&AH:&AH:&AH:&AH: 1&AH:&AH:&AH:&AH:&AH:&AH end /S08::$dd00::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Software analysis and reconstructive therapy, a historical view on "cracking". by Pontus Berg Cracking was defined as the removal of copy-protection, and for this reason the product had to feature protection in the first place! Most "originals" of today do not feature any protection, but I guess what most people are after is just introlinking and crunching (correct me if I'm wrong)! I'll brief you on the whole train of thought! Cracking was much about being able to analyze someone elses code. This did not mean that you had to be able to understand exactly what each instruction did, but from the context you had to be able to tell the main purpose of a section of code. From this followed that you had to be able to know A LOT about coding. The better you knew how to code, the better was your chance of getting decent as a cracker. This was a very difficult thing, mind you. How could you detect a loader routine from the rest of the code if you didn't know 6502? The answer is that you simply couldn't! A lot of people had to learn on the fly. By digging into other people's code you got a feeling for 6502, and this experience built many a legend. If you ever saw a good cracker in action they could scan the memory with the I* command of their monitor utilities and tell what parts of the memory did what and how. :) This is all nice but what exactly went on in the mind of the cracker? Well, let's explore briefly the generalities on cracking tape games, as they are virtually non-existent in our Commodore world of 1996 and are therefore not a political hot-potato so to speak :). For tapegames, the fact that the original is on tape is the hardest part. There are transfers that copies tapedata to disk for most common tapeloaders. Doing it by hand is not something you have to do every day, but it's something you must be able to do if you want to call yourself a cracker! Mind that it's not all that easy! If you take a look at the persons who call themselves crackers today, only a very limited few are able to do this! Tapetransfer SYS 63276 This loads the header into the tapebuffer at $033c. You get the name on screen and can press space/CBM key to get back to the prompt. It won't start loading as it would have if you had written LOAD. You can now modify the tapebuffer. The five first bytes are 03 (Not relocatable file), Low/High startaddress, Low/High endaddress f.ex. 03,9f,02,3c,03 This loads a file at $029f ending at $033c. If you modify this into 03,9f,12,3c,13 You'd get it on a place where it won't start in your face (i.e. $129F)! By the way, if the start says 03,01,08,XX,YY then the game loads to basic, and you can then just type LOAD and after loading it won't autostart (unless you pressed shift+runstop), but can be saved normally to disk (unless it exceeds the limits of basic by loading over $a000). Why $129F - Well as it's easier to disassemble the code if the lowbytes are the same as the original. SYS 62828 Will load the file at the address you asked for with the pointers! (i.e. $129F) From here you are on your own, as no two tape loaders are exactly the same! I cannot say anything general about tapeloaders! If you decidper the loader and find no startaddress in it, then it might be as it's overloaded during loading. Selfmodifying loaders are frequet to prevent you from tempering with them. I usually resource the loader and place it elsewhere in memory. I can then safely transfer the files! The tapes don't usually feature any protections more that the fact that they are on tape. I seen a few games that set the timers before loading and checked them afterwards to ensure you hadn't interrupted the loading but This is rare! Last Ninja II was like this! OK, after this you have the game on disk. A one-filer shall now work 100%, no matter if it's transfered from tape or if you got it directly on disk. A onefiler 1. Depack it (if packed or crunched) 2. Remove crap that only take room and is of no use! (This is what I do GOOD that makes my cracks shorted than most of the others!) 3. Scan for trainers! (I use Action Replay first. If it finds them, I saved myself a lot of work!) 4. Install the trainers in a trainer menu & put it in memory of the game! There's almost always room for that! 5. Pack the game 6. Add the intro 7. Pack the game again (only needed if you gain something from this!) 8. Crunch Multifile games Additional work compared to the above: 1. Locate the loader and remove it 2. Analyse the code for the old loader and make yours load the correct level from the internal levelcounter of the game! 3. Replace the loader with your own one (featuring a decruncher) including the information you got while analyzing the code (see 2) 4. Crunch the levels In detail Ok you might then need some guidance in each of the steps! I guess depacking is the most important part! The depacker/decruncher starts somewhere (usually basic, at $0801), and you can then pretty easily follow the code in it. The action replay has the AWSOME feature "Set Freeze". You disassemble the code in freezemode (N.B.) and then enter a SF the the opcodes. F.ex. 4000 AD FF 4E LDA $4EFF You modify to: 4000 SF FF 4E LDA $4EFF ^^ and press return! You now get: 4000 20 D3 DF JSR $DFD3 (Or something like this) I saw QED/Triangle working, and he did a version of this using his Expert Cartridge. He did pretty much the same but manually. He installed this instead of the "SF" CLC BCC (To the CLC) After a while, when the program was surely in the infinite loop, he slammed RESTORE to enter his monitor. I have used this some times myself, when the SF was not working for some reasons (mainly as $01 was set to something that prevented SF from working). Back to depacking OK, back to the depacker! You enter this SF at the place where the decruncher jumps to the next step in the process. It might be starting the next depacker and it might be starting the game! Remember that most decrunchers are different, so you cannot take for granted that the skills from one apply on another one! Some VERY GENERAL hints: Most of the times, the startup looks something like this: SEI/CLI/NOP ;Either of these LDA #$3X ;Where X is almost always 4-7 (most often 7) STA $01 JMP $YYYY ;Where YYYY is the start address and the place to put your SF ;Set on top of the $4C, i.e. the actual jump instruction. Most decrunchers has this code in the area $0801-$0a00, but the AB cruncher and CruelCrunch has it in the very end of the file (in the last two blocks). This is where I get to be so concrete that it would be best if I had an example to show from! This will have to be all for now.. :) Pontus Berg /S09::0100h::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: - A Quick Overview of CP/M - By Mike Gordillo What is CP/M? CP/M is an operating system available for microcomputers using the Zilog Z80 Microprocessor. As an operating system, CP/M is responsible for directing your computer's resources to fit your needs. It executes software (programs) in response to commands you enter through the keyboard (console), and once executed, your programs can use CP/M to perform many tasks. For example, CP/M software can manage databases, copy files, process spreadsheets, analyze your income tax, print your forms, or play your favorite video games. CP/M 3.0+ on the Commodore 128 is simply a version of CP/M 3.0 that has been altered to better fit the particular needs of the Commodore 128 and its users. Aside from a few cosmetic differences and the ability to use the peripherals (drives, modems, etc) of the C-128 System, there is not much to distinguish general CP/M from the C-128 version. Your C-128 can execute virtually all the software widely available for CP/M machines. However, please note that CP/M software intended specifically for a certain CP/M machine may not necessarily run or run-as-intended on another CP/M machine. How do I start CP/M? Unlike the C-64 and C-128 native modes, CP/M must be started from the CP/M 3.0+ System Diskette. The standard start-up procedure requires you to have one drive set to device #8. All you do is insert the System Diskette into the drive and type BOOT from within the C-128's Basic 7.0 mode. CP/M should now "boot up" from the diskette. If this does not happen, clear memory by turning off the C-128 and the drive. Put the CP/M System Diskette in the drive and turn the C-128 and the drive back on. You should now see CP/M assume its normal diagnostic "boot up" procedure. Once that is complete, CP/M will announce itself proudly as "CP/M 3.0 on the Commodore 128" and provide you with its version date. The 28 May 87 CP/M 3.0+ version, for example, is the last and most popular official version for the C-128. Other "non-official" versions exist for the C-128, most notably the BIOS6-ZPM3-ZCCP enhancements -- but that's the subject of another article. CP/M is a command-line interface! CP/M is a command-line interface. This means that your instructions to CP/M must be entered as commands to the system from the keyboard (as opposed to mouse control in popular Windowing environments like GEOS). You enter commands via the A>, B>, C>, D>, E>, or M> prompts. These prompts tell you which disk drive (device) you are currently using as well as letting you know that CP/M is ready to receive your orders as soon as possible. For example, if I see the A> prompt, I am using device 8, but if I see the B> prompt, I am using device 9, and so on. I can change between devices by simply entering the appropriate letter and a colon, as follows: A> B: (Changes from Drive A to Drive B) B> C: (Changes from Drive B to Drive C) C> A: (Changes from Drive C to Drive A) A> (Back to Drive A) The E> and M> prompts are special cases. Drive E is not a real drive/device, rather, it is a Virtual Drive used for copying purposes when only a single real drive is available. Drive M is not a physical drive at all. It is assigned to the Ram Expansion Unit as a RAM drive. How is the CP/M Command Structure organized? CP/M has six built-in commands: DIR, DIRSYS, ERASE, RENAME, TYPE, USER. These commands are part of your CCP.COM file (Command Console Processor) and they make it easy for us to perform basic level housekeeping. DIR allows us to call up a disk's directory of files. DIRSYS does the same thing except it shows us only files tagged with a system-flag (eg. hidden files). ERASE and RENAME allow us to erase and rename files while TYPE is used to display text files on the screen. USER lets us switch between different user sections on a diskette. A CP/M diskette can have 16 user sections (0 to 15) in which files placed in one section are logically separate from files in different sections. User sections are CP/M's way of allowing for better organization of files through partitioning. Any other "commands" you might run into are known as transient-utility commands. Transient-utility commands are simply executable programs that reside on a diskette instead of being built into CP/M itself. They are usually identifiable on the diskette by virtue of their .COM extensions. For example, if I call up a disk directory using the DIR command, as follows: A> DIR BASIC.COM DISC=OV.ERY ISAGREAT.MAG SORT.COM TERM.COM This tells me that on Drive A (device 8), the files basic.COM, sort.COM, and term.COM are transient-utility command files. Notice that there is no DIR.COM available to call up a directory because the DIR command is a built-in command. Does my System Diskette have Transient-Utility (T-U) Commands? Yes, Commodore put several useful T-U commands into the CP/M 3.0+ System Diskette. You should have the following in order to begin to effectively use CP/M on the C-128, as follows: A> DIR C1571.COM CONF.COM FORMAT.COM KEYFIG.COM HELP.COM PIP.COM C1571.COM is a neat T-Utility that will double your 1571's SAVE speed by disabling the automatic verification involving the saving of a file to the diskette, as follows: A> C1571 [a (Disables auto-verify on Drive A - Device 8) CONF.COM is a GREAT T-Utility that permits us to change many system-default parameters like baud rate, screen colors, printer assignments, etc. When I first started, I was very very frustrated at what appeared to be immutable artifacts in the operation of the C-128's CP/M. In other words, I could not CONFigure the system as I wanted. This utility changed all of that. For example, I used to have a 4040 dual drive which I hooked up to the system intent on using it under CP/M. I found to my dismay that I could only access one out of the two drives huddled in the 4040 bay. CP/M had no way of knowing that the single device it saw (the 4040) had more than one drive! Along came CONF.COM to the rescue! I simply typed up CONF DRVB = 8-1 and voila, the second drive in the 4040 became Drive B (which would normally be device 9). CONF is also great at modifying CP/M itself when needed. I recall one time when I was using another T-Utility that had problems with the Ram Expansion Unit under its normal device assignment. In other words, the utility I was using could not handle a drive M. I used CONF's POKE ability to change the drive M assignment of the R.E.U. into a drive B assignment, as follows: A> CONF POKE fbd3 = 96fb (Reassigns the REU from drive M to B) FORMAT.COM allows you to format your diskettes in a variety of CP/M formats, all of which can be read by the C-128's CP/M. KEYFIG.COM is a T-Utility which allows you to redefine ALL keys on the C-128 except the SHIFT and SHIFT-LOCK keys, the 40/80 DISPLAY key, the CONTROL key, and the COMMODORE key. You can assign keys to have up to four different values/functions to suit your needs. HELP.COM is a good manual of CP/M commands and command syntax. It serves as an index of commands and tells you how to properly use them. PIP.COM is the standard file-copy T-Utility. I use it routinely to create backups of my files as well as creating new system diskettes in cooperation with the FORMAT.COM utility, as follows: A> FORMAT (Use the Format utility to format drive B) A> PIP B:=A:CPM+.SYS (Copies the CP/M system file from Drive A to B) A> PIP B:=A:CCP.COM (Copies the CCP.COM file from Drive A to B) Is that all I can do with CP/M? No, Commodore packaged CP/M for the C-128 with just the basic entry level material necessary to begin to use CP/M effectively. CP/M can do much more but like all things concerning computers, you need a good measure of software to make the best use of what you've got. There is nothing harder for the novice than to accumulate enough software to increase his and his system's proficiency. I recall many times thinking how useless CP/M was to me. After all, I could do so much more in C-64 and C-128 modes! However, once my software base had risen beyond what the System Diskette offered, my analysis of CP/M changed from useless to useful. In other words, CP/M productivity is in software? CP/M's strength lies in the large software base available for it. CP/M is the first operating system to showcase the functionality of microcomputer database and spreadsheet applications on a large scale. I regularly keep large databases and spreadsheets on the C-128's CP/M and then use other CP/M productivity programs to transfer them to and from other types of systems. Furthermore, some of the best software compression programs and computer languages are only available for the C-128 whilst in CP/M mode. With over ten thousand software titles to choose from, there is nothing you can't do! Where can I get CP/M software? You can get good CP/M public domain software from CP/M User's Groups throughout the United States and Canada. There is also substantial CP/M support in Japan and in Europe. Commercial software is readily available from appropriate vendors (usually listed in user group publications). The most substantial concentrated source of CP/M software is undeniably the Internet. The Internet is a collection of various computer networks linked together throughout the world. There are thousands of megabytes of CP/M programs (from 1976-1993) available there. A few popular 'CP/M sites' are as follows; oak.oakland.edu /pub/cpm ccnga.uwaterloo.ca /pub/cbm/os/cpm And pray tell, how do I transfer CP/M software into the C-128? Well, there are a number of ways. The most efficient way is to copy files from one CP/M disk onto another. The C-128's CP/M can read the CP/M diskettes from Epson, IBM, Kaypro, and Osborne CP/M machines. You can also use terminal programs if your CP/M's version-date is later than 4 DEC 85 (ie., earlier versions lacked access to the modem port) in order to transfer material via the phone lines. The most inconvenient way, however, is to use transfer programs (from either CP/M or other modes) to read material onto your CP/M diskettes. Come on, I'm looking for something simple. Is there a CP/M CD-ROM? Sure is! A few people out there decided to put several megabytes of CP/M software on CD-ROM (!) and just a few months ago, someone wrote a CD-ROM reader for C128 users with a CMD Hard Drive (SCSI port)! The "Walnut Creek" CD-ROM and "CD-ROM Commander" are two very exciting products for CP/M 128 users, as these items allow access to hundreds of megabytes of CP/M software. (Please consult the internet newsgroup 'comp.sys.cbm' for more details). Final thoughts... CP/M complements the C-64 and C-128 modes very well. I feel that in the productivity area, the C-128 would be very deficient otherwise. I have yet to see productivity packages in the native modes that are as efficient as the ones I use under CP/M. The structure of the CP/M operating system is also more amenable to file transfer and file management. My Ram Expansion Unit has never been as easy to work with in the C-64 and C-128 native modes as it has been under CP/M. CP/M may seen complicated at first but it is actually quite easy to understand. Once you've mastered it, you may never go back. ----- Mike Gordillo is an expert in CP/M and Z80 programming as well as a devout Commodore fanatic over the past twelve years. He may be reached on the internet as s0621126@dominic.barry.edu for general comments or questions. /S10::0100h::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: The BIOS-R62a/ZPM3/ZCCP Commodore 128 CP/M 3.0+ Upgrade Package and a bunch load of utilities! by Mike Gordillo Preamble This package was an in-house project for mostly myself and a few of my friends. I released this last year to the general internet community, and as far as I know, all software therein is public domain. What to do: FTP to ccnga.uwaterloo.ca Directory is /pub/cbm/os/cpm Download (remember to set binary flags) the following: zpm-user0.zip zpm-user1.zip upgrade-user0.zip Unzip them on your unix/vms/dos box and put them on a C128 CP/M 1571 or 1581 boot disk (eg., BBR 4.1) in the following manner: All files from zpm-user0.zip go to USER 0 on your CP/M boot disk. All files from zpm-user1.zip go to USER 1 on your CP/M boot disk. IF you have any of these: Swiftlink cartridge, an ASCII printer, absolutely NO ram expansion whatsoever, a 1581 drive, you will probably need to take a look at upgrade-user0.zip. It contains replacement files that satisfy the hardware I just listed. IF so, you MUST use the replacement files to insure proper operation. All replacement files MUST go to USER 0 on your CP/M boot disk. Please READ the read.lis file in the upgrade-user0.zip archive for more details. Note: If you unzip these archives on a VMS system, chances are that CPM+.SYS will be renamed to CPM.SYS. You MUST make sure that you rename it back to CPM+.SYS on your CP/M boot disk, otherwise CP/M will not boot. For more information on BIOSR6 and ZPM3/ZCCP enhancements please consult Randy Winchester's CP/M article in the online magazine, C= Hacking issue #5. Abstract This package is provided as a courtesy to C128 users. Meaningful CP/M system-generation utilities are not provided with the C128 CP/M System diskette. Most C128 users would therefore have difficulty in assembling a package like this. Also, the lack of easily available sources for CP/M software brings its own share of hardships. The utilities included are meant to provide new tools for the C128 user and maximize the features of BIOS-R62a, ZPM3, and ZCCP. Filelist zpm-user0.zip: Length Date Time Name ("^" ==> case ------ ---- ---- ---- conversion) 512 01-03-95 11:41 autotog.com 4480 01-03-95 11:41 b5-driv3.com 512 01-03-95 11:41 bye.com 128 01-03-95 11:41 c128-xgr.z3t 1024 01-03-95 11:41 c1571.com 3200 01-03-95 11:41 ccp.com 24576 01-03-95 11:41 cpm+.sys 1152 01-03-95 11:41 echo.com 3840 01-03-95 11:41 format.com 16384 01-03-95 11:41 format22.com 640 01-03-95 11:41 format81.com 3328 01-03-95 11:41 if.com 3456 01-03-95 11:41 loadseg.com 5376 01-03-95 11:41 mkdir32.com 256 01-03-95 11:41 names.ndr 17536 01-03-95 11:41 qterm.com 17408 01-03-95 11:41 rdcbm.com 8192 01-03-95 11:41 salias.com 3456 01-03-95 11:41 setpth10.com 1024 01-03-95 11:41 startzpm.com 8192 01-03-95 11:41 superzap.com 24320 01-03-95 11:41 trans128.com 7424 01-03-95 11:41 v.com 15488 01-03-95 11:41 vde.com 2816 01-03-95 11:41 verror.com 15744 01-03-95 11:41 vlu.com 2048 01-03-95 11:41 zdt12.cfg 7936 01-03-95 11:41 zdt12.com 15232 01-03-95 11:41 zfiler.com 1536 01-03-95 11:41 zinstal.zpm ------ ------- 217216 30 zpm-user1.zip: Length Date Time Name ("^" ==> case ------ ---- ---- ---- conversion) 128 01-03-95 14:47 clrhist.com 3328 01-03-95 14:47 conf.com 5996 01-03-95 14:47 conf.hlp 3072 01-03-95 14:49 copy.com 3200 01-03-95 14:49 date.com 2816 01-03-95 14:50 del.com 3712 01-03-95 14:51 diff.com 3712 01-03-95 14:51 dir.com 1280 01-03-95 14:52 dirnames.com 2944 01-03-95 14:52 diskinfo.com 1664 01-03-95 14:53 image.com 6912 01-03-95 14:53 lt.com 12928 01-03-95 14:55 pmext.com 3712 01-03-95 14:58 ren.com 1792 01-03-95 14:58 rsxdir.com 4736 01-03-95 14:59 unarc.com 12288 01-03-95 15:00 unarj.com 1408 01-03-95 15:02 undel.com 3456 01-03-95 15:03 unzip.com ------ ------- 79084 19 upgrade-user0.zip : Length Date Time Name ("^" ==> case ------ ---- ---- ---- conversion) 24576 01-03-95 15:41 cpm+.sys 3840 01-03-95 15:40 f1581.com 256 01-03-95 15:41 names.ndr 17536 01-03-95 15:46 qtermsl.com 732 01-03-95 14:08 read.lis 1024 01-03-95 15:41 startzpm.com ------ ------- 47964 6 Condensed History BIOS-R62a- Default System Baud Rate set at 134. Warning: Term programs will modify this. Higher Baud = Faster Keyboard Scanning = Slow CP/M Re-implemented support for PETSCII printers (code from BIOS R4) LST Settings : PRT1=Dev #4, PRT2=Dev #5, Secondary Address = 7 CONF utility's PRT assignment options will not work because of changes made back in BIOS R4. ASCII printers are available with the ASC-PRT implementation of BIOS-R62a (included..see BIOS R5). -CPM+.SYS for ASCII printers is included in upgrade-user0.zip BIOS-R62 - Default System Baud Rate set at 75 (not enough Keyboard Scanning). Added support : C=1581 Official Format! (F1581.COM will allow you to make/create 1581 boot disks... included in upgrade-user0.zip). MAXI 71 and GP 1581 Format supported (see BIOS R5). ASCII printers still default. -Randy Winchester BIOS R5 - Added support for new hardware: Quick Brown Box (E:), Drive D: Added new definitions to the disk-parameter-table. Maxi 1571, GP 1581 formats. Use format22 & format81 with these MFM types. ASCII printers now default. PETSCII tables not supported. LST Settings : PRT-D4=Dev #4, PRT-D5=Dev #5, Secondary Address = 5 -Randy Winchester BIOS R4 - Removed the 40 column routines, the virtual drive, and Drive D:. Removed Printer Buffer (Lord knows why!?) Added a screen dump feature. Fixed several BIOS errors as well. -James Waltrip IV ZPM3 BDOS- (see below) -Simeon Cran ZCCP CCP - (see below) -Simeon Cran **DISCLAIMER** ** **You are free to distribute this package with the following conditions; ** ** A) This package cannot be sold. A copying/handling ** fee of no more than $5 1993 US dollars is allowed. ** ** B) This package shall remain whole. No item may be ** distributed apart from the rest of the package. ** There is a degree of hidden cross-dependency between ** some items. Split them apart and you may get ** unpredictable results! ** **This package is NOT under any warranty or guarantee of ANY kind! Description BIOS Upgrade - The C128 28 May 87 CP/M 3.0+ Version BIOS was reworked to remove useless code (40col screen and Virtual Drive...not really useless to some of us? Argghhhh! :) and to correct a few CP/M 3.0 BIOS errors while adding a screen dump feature (ALT key is used as a toggle). End Result = Faster, more "peppy" CP/M 3.0+ operation. BDOS Upgrade - This is the ZPM'ing of CPM! Think of this as a way-overdue correction for an anachronism. Much of the original BDOS is written in slower Intel 8080 code. The ZPM3 BDOS upgrade rewrites things in faster, richer Zilog Z80 code while adding some goodies (eg., command history buffer, enhanced command line editing, automatic command prompting) and correcting some CP/M 3.0+ BDOS errors. ZCCP Upgrade - The last nail in the coffin. The original CCP.COM is replaced by a more flexible beast. Neat things are now at your beck and call. ZCCP features : ZCPR 3.3 Compatibility (see below) -Does not support FCP but supports flow control internally with an IF.COM utility present. -RCP is not implemented (That's what REUs are for :) -Cannot load ZCPR 3.4 "type 4" programs -Cannot re-execute loaded programs sans re-loading Z3T Termcap (ZCPR 3.3 graphics support) Named User Groups/Directories Command Search Path System Environment Block Flow control processing for batch files Extended Command Processor for batch files Multiple commands on one line Superior error handling Up to 4 Shell stack levels may be defined Direct loading of .RSX files without GENCOM (LOADSEG) Put these all together and you have the ultimate CP/M system for your C128. Compatibility BIOS R62a - 99.00% Compatible with stock CP/M 3.0+ C128 system. -A problem concerning printing is listed in the Condensed History section. (Note: Programs that call the 40col screen will see a NULL40 label -i.e., They will run but they won't be able to do anything in 40cols) ZPM3 BDOS - Fully 100% compatible with stock CP/M 3.0+ BDOS segments. (Note: Some rare programs *demand* the CP/M 2.2 BDOS..yuck!) ZCCP CCP - ZCPR 3.3 compatibility as seen in the Description section. Environment info is larger than before. Slightly more TPA is used or some additional high memory is being toyed with. For example, I shortened TRANS128's buffer and that did the trick. (Note: Some of Steve Goldsmith's C128 specific programs will will crash with the ZCCP.RSX in operation). Additional Notes -Look at the ALIAS (included) batch file (type SALIAS STARTZPM on the command-line). Notice how it optimizes the system for REU use. You may change this as long as you keep the following in mind : ZCCP *requires* : LOADSEG commands for NAMES.NDR and *.Z3T Termcaps. At least *ONE* SETPTH drive search/path entry. Quick Summary of STARTZPM batch file (included): 1) Loads up Directory names. 2) Loads up Directory paths. ($$$$ = Current Drive/User DIR) 3) Executes a few .COM files. 4) Copies all Command Utilities to M1: (COMMAND Directory). -Utilities copied over to the REU (as seen in STARTZPM) are general purpose utilities meant to replace the built-in commands of the standard CCP.COM. With the excellent path setups in ZCCP, utilities in the speedy REU become transparent. (Note: If you have NO ram expansion (eg., a drive M:) you NEED to take a look at upgrade-user0.zip, as mentioned earlier). -Multiple commands on the command line must be separated by semi-colons. (Note: Semi-Colons are used in CP/M 3.0+ to append file passwords. Use the SET.COM utility (SET [DEFAULT=PASSWORD]) to set a password which can be used without your intervention on every file you access. In any case, you can assign passwords to user groups (under ZCCP) with the mkdir32 utility, which is simpler than dealing with CP/M 3.0+ SET.COM password assignment schemes.) -The following keys have been already configured to work best with ZCCP: They are user-definable with KEYFIG or LOAD/SAVEKEY utils (not included). -CRSR-UP/DOWN - CRSR-LEFT/RIGHT KEYS UP = CTRL-E DOWN = CTRL-X LEFT = CTRL-S RIGHT = CTRL-D CTRL-E and CTRL-W = Forward and Backtrack through Command-History Buffer. CTRL-X = Delete everything to the left of the cursor. -ARROW KEYS (at the top of the keyboard) UP = CTRL-E DOWN = CTRL-X LEFT = CTRL-A RIGHT = CTRL-F CTRL-A and CTRL-F = Autotab left and right. -CLR/HOME = CTRL-H (BackSpace) INST/DEL = CP/M RUBOUT KEY -ZCCP does not support printable control characters (eg., ESC, CTRL-Z) on the command line. In order to change screen display characteristics use the CONF.COM utility (included) instead of, for example, using ^[^[^[. Also, although CTRL-Z will not clear the screen anymore, you can use the built-in CLS command instead. (Note: You can still use printing codes in programs.) -Consult the C128 system manual for the full list of ADM-3A to C-128 key assignments and sequences. -- For general comments on this article, feel free to contact Mike Gordillo at s0621126@dominic.barry.edu :::::::::::d:i:s:C=:o:v:e:r:y:::::::::::::::::i:s:s:u:e::1:::::::::::::::::::: \H01::::::::::::::::::::::::::H A R D W A R E::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: BEYOND STEREO The POWER-SID Model 2400 : It May Not be THX, but it's Taking the Commodore One Dimension Closer A preview by Shaun Halstead A few months back, as I was working on some music using Robert Stoelle's Stereo Sid Editor, I got to thinking about how many voices I would need for this and that, and I realized that I was going to need more than twice as many as I had available. I called up Nate Dannenberg (a.k.a. _Tron_) to see if he knew of any way to get more voices; he said that the only feasible way was to add more chips, of course. So, being the annoying pest I am, I got to thinking of ways to do just that, and the concept of surround sid board was born. Carrying eight, count 'em, eight, sid chips, at three voices each, combined to give four main channels (front and rear, with left and right on each), working in tandem with the computers stock sid chip, which acts as a center channel, the Power-Sid is carrying the Commodore into a new dimension of sound. Well, to make a long story short, between the two of us, we developed the basic components, layout, and operation, including addressing options. Currently, the board is designed to mount vertically, similiar to the Super-CPU developed by CMD. This was done mainly to conserve space behind computer, but has another advantage: by mounting the card vertically, a pass-through port is easily installed (it was a given from the start that a pass-through be available). Until recently, we were having considerable difficulty in solving the pass-through mounting problem (i.e. where to put it), until Nate found a way around it, based on the Super-CPU. The actual construction will not be easy, by any means, but it should be quite strong, durable, and nice in overall appearance. The model described here (model 2400) will measure roughly 4-by-4 inches, contain eight sid chips, two stereo jacks, addressing and support circuitry. The support circuitry includes an enable/disable switch, activity LED, an addressing switch, selectable between $DE00 and $DF00, and a pair of LEDs indicating the current address, a two/four-channel selection switch and dual-color LED to indicate the current mode. The only difference between the model 2400, described here, and the model 1200 is that the 1200 carries only 4 chips, and offers fewer voices per channel, but is none the less, fully featured. Currently, software is being developed by Nate and I, and we are working on a port to support his up and coming digital output card for the expansion port. Look for an extensive follow up in this journal when the board enters the prototyping stage. -- The author, Shaun Halstead, can be reached at tesla@onyx.southwind.net, and Nate Dannenberg can be reached at tron@wichita.fn.net, or catch them on IRC channel #C-64, as _Tesla_ and _Tron_, respectively). \H02:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * The 8 bit Modplay 128 Board * by -- Nate Dannenberg -- Have you ever listened to Digital sound on your Commodore and wondered where all the noise is coming from? Ever tried messing with Pulse Width Modulation, only to realize that it just doesn't have the clarity and impact you need for a particular project? Want to make your Commodore sound better than it ever has using 8 bit sound? Well, now's your chance... Included here is the procedure for building a two channel 8 bit DAC circuit to plug into a Commodore 64 or 128 (works in both modes), which outputs in stereo two-channel sound. Actually, the 8 bit DAC chip we will be installing does four tracks, which are mixed using four 1K resistors into two channel stereo sound with a total resolution of 9 bits per channel, or 8 bits per track. This circuit is based around the Maxim Electronics MAX505xCNG chip, where x refers to a number of chip-packaging options provided by Maxim. The recomended chips are the MAX505 A- or B- CNG (24 DIP Narrow Plastic package). This chip contains four 8 bit DAC circuits, each with 5 volt rail-to-rail swing, internally buffered and coupled with precision unity-gain followers that slew at 1V/uS (If you can understand all that jazz, you're a better man than I). Each DAC accepts it's own reference voltage input (not to exceed the power supply voltage, which is 5 volts in this project), and each generates it's own buffered output. Originally, this circuit was designed to work on a Commodore 128 with the upcoming MODplay 128 software, also one of my projects. Using this software, and outputting to this circuit, I get about 8.2 Khz out of it in four track, two channel, 8 bit-per-track (9 bit total) stereo. Since this circuit is relatively simple to access, it can be used in many other applications, from audio output from a simple RAW or WAVE player type of program, to more complex applications requiring a controllable analog signal. With the right timing, you could probably use it to control the sync signals to an RGBI monitor! Anyways, let's get on with it. First we need to get the legal stuff out of the way... Disclaimer: I take no responsibility for any loss or damages occuring from the use of this device, or from the instructions and proceedures described in this text. Any damage resulting from the use of this text is purely the responsibility of the builder/user. [Ed. Note : The editor nor disC=overy magazine is not reponsible for any loss or damages occuring from the use of this device, or from the instructions and procedures described in this text.] Here is the parts list: 1) Maxim Electronics MAX505ACNG (or -BCNG) DAC chip. 1) 12/24 .156" Female edge connector. 1) 1/8" stereo (three-conductor) miniplug. 4) 1K, 1/8 or 1/4 Watt resistors of either 5% or 10% tolerance. * a bit of thin wire (preferrably wire-wrapping-wire) * a bit of heavier wire (about 20 guage) * solder (silver-based is preferred, but lead based works too) * A low-wattage soldering iron (mine is only 20 watts) Optionally, you may build this onto a printed circuit board, which will require a piece of double-sided copper clad board about 1" by 2.5", a resist-ink pen or dry transfers, and some Ferric Chloride (PCB etchant). [Ed. Note : Maxim Electronics : 1-800-998-8800 ; Radio Shack has the jack and they do carry a .156" connector but with 22/44 leads. I had to cut it to 12/24 in order to match the userport. Also, it must be noted that soldering to a socket is less of a risk than soldering to the chip itself.] I built the prototype by mounting the chip directly to two pins of the user port connector. Since the design is so simple, I will describe the procedure for building the circuit using the prototype method, without using a printed circuit board. Here we go: 1) Turn the edge connector to point the solderable pins towards you. Cut off pin 1, pins 3-7, and pins 10-12. These are on the TOP row, with pin 1 being on the left end when the connector is held as above. left 1 2 3 4 5 6 7 8 9 10 11 12 right 2) Cut off pin A and B. This is on the bottom row, second from the left. Remember that as with most Edge connectors, there are no pins G or I. Instead the pins are lettered like this: left A B C D E F H J K L M N right 3) Align pins 12 and 13 of the Max chip, with pins H and F (respectively) on the User Port plug. Make sure the chip and plug are right side up. now bend the chip's pins around and under the plug's pins, and solder. 4) Using a series of short wires, connect the following using ordinary point-to-point soldering. Chip Plug 16 C 15 D 14 E 13 F (already soldered) 12 H (already soldered) 11 J 10 K 9 L 5) Using more point to point soldering, connect the following: Chip Plug 22 two 19 M 18 nine 17 eight 8 N 6) Turn the device upside down and make the following connections on the back side of the chip. Be sure not to confuse your pin-layout! Again, plain old point-to-point soldering is the key. Pin 20 to pin 21, Pin 21 to Pin 22, Pin 22 to Pin 4, Pin 4 to Pin 5. Pin 8 to Pin 7, Pin 7 to Pin 6, and Pin 6 to pin 3. 7) Turn the circuit back right-side-up again, and connect one end of each of the four 1K resistors, to the Max chip, pins 1, 2, 23, and 24. 8) Now Take the resistors connected to pins 2 and 23, and connect the free ends together. Connect this point to the Miniplug TIP tab. 9) Take the resistors connected to pins 1 and 24, and connect the free ends together. Connect this point to the Miniplug SLEEVE tab. 10) Connect the Max chip's Pin 6 to the Miniplug GROUND tab. 11) Take a piece of the heavier wire, fashion a simple pull-handle by running a wide loop of it between the holes at each end of the plug. For strength I recommend soldering the ends together. [Ed. Note : Please observe : Pins 1 and 24 are used as RIGHT output and pins 2 and 23 are used as LEFT output. On a 1/8" stereo miniplug jack from Radio Shack (#274-249a), you will see three prongs. The prong closest to the opening of the jack is the GROUND, and for reference's sake we will consider that this prong is at the base of the jack. The other two prongs are on the back of the jack and are aligned one 'above' the other. The one that is on the base is the SLEEVE and the one above it is the TIP.] Your 4 channel DAC circuit is now ready to use. To test the circuit, you can run this short BASIC program on a Commodore 64, or a Commodore 128 in 64 or 128 mode. In 128 80-column mode, you may want to type 'fast' and hit return before running, to make the test higher pitched and a bit more accurate. 10 u=56577: poke u+1,63: poke u+2,100: input "channel (1-4)";c$: c = val(c$) 20 if c<1 or c>4 then 10 30 if c=1 then ch=248 40 if c=2 then ch=252 50 if c=3 then ch=240 60 if c=4 then ch=244 70 poke u-1, ch 80 for x=0 to 255: pokeu,x: next 90 get a$: if a$="" then80 100 goto 10 What you should hear coming out from the desired channel is a sawtooth wave, simialar to the sawtooth save the SID chip produces, but of course a tad * distorted * since this is in BASIC. Press any key to stop the test. In machine language, these instructions should produce a similar test.. POKE 250,speed: POKE 251, chan_index: SYS 3072.. speed will control the pitch of the sound. Chan_index is 248 for channel 1, 252 for channel 2, 240 for channel 3, and 244 for channel 4. Press the spacebar to stop the test. Hexadecimal Decimal equivalent START * = $0C00; 3072 SEI LDA #$3F; 63 STA $DD02; 56578 LDA #$FF; 255 STA $DD03; 56579 LDA $00FB; 251 STA $DD00; 56576 LDY #$00; 0 LOOP STY $DD01; 56577 LDX $00FA; 250 DELAY DEX BNE DELAY INY LDA $DC01; 56321 CMP #$EF; 239 BNE LOOP CLI RTS Accessing the board via your own software is very simple.. You need to use Machine code if you are planning to access more than one channel of the board. If you plan to use a single channel, just POKE 56576,248 and run your player routine. This will select channel 1 (left side) to send your output through. In machine code, you use a single LDA:STA pair to select the channel, and just stuff your data into $DD01, something like the above. The hardware will take care of the output, and will see to it that the byte you send out is properly clocked and that it goes to the correct channel. The User port contains a total of 10 easily programmable data lines (the others require more complicated methods to use). These lines are broken into two sets. The first set, the data bus as I like to call it, consists of the 8 lines than make up the User Port's PB0-7 area. These bits are all present at location $DD01. The data direction regiter for this location is at $DD03. A 1 bit there means an input, while a 0 bit signifies an output. The other set consits of two bits that sit at location $DD00, these bits are PA2 and PA3, also known as RS232 data out, and Serial ATN in, respectively. These two bits serve as a mini-address bus, and are used to select the correct channel to comminicate with. Since the hardware inverts the output of PA3, it was necessary to re-invert this bit in software, which is why the channels are being selected with such odd numbers. Also, since location $DD00 controls the 16K memory bank seen by the VIC-II chip, you must keep the VIC pointing to bank 0 (by setting bits 6 and 7) if you want to keep the VIC 40 column display in proper order. This explains why all of these numbes are 240 (#$C0) or higher. Most DAC chips require some sort of clock signal to pass data into the chip. The MAX505 is no exception. In order to lessen the time needed by the computer, we wil ise the User Port's PC2 line, a low active clock line that fires every time a byte is sent or received via the PB0-7 lines. This line was intended to drive the /FLAG input of another C64, or other hardware device, however, it also serves as a useful clock signal for our chip. The MAX505 requires you to select the channel first, write the data byte to it's data bus, and then pull the /WR line low for a brief moment. Thus we write our code like this, to do these actions in proper order: LDA #$Cn ; n is 8, C, 0, or 4, for Channels 1, 2, 3, and 4 ; respectively. Channels 1 and 4 are wired for left ; output, while 2 and 3 are wired for right. STA $DD00 ; This actually sets the channel number. LDA your_data_here ; Use whatever method you need to get the next byte of ; Sample data into the accumulator. STA $DD01 ; Send the byte to the User port, automatically ; firing PC2. That's pretty much it! The MAX505 chip is designed to handle in excess of 100,000 samples per second, per channel. In fact, according to the specs, it can go as high as 1 million samples per second, per channel. Below you will find a pinout diagram for the MAX505 chip, to aid in performing the steps given above for assembling this circuit. This is a duplicate of the diagram found on page 1 of the spec booklet that comes with the MAX505 family. TOP VIEW ___ ___ |. `-' | VOut B [ 1| |24] VOut C VOut A [ 2| |23] VOut D VSS [ 3| |22] VDD VRef B [ 4| MAXIM |21] VRef C VRef A [ 5| MAX 505 |20] VRef D AGND [ 6| |19] A0 DGND [ 7| |18] A1 /LDAC [ 8| |17] /WR (MSB) D7 [ 9| |16] D0 (LSB) D6 [10| |15] D1 D5 [11| |14] D2 D4 [12| |13] D3 |_________| DIP/SO/SSOP Have fun with this circuit! I built mine in about 30 minutes, and it has become my default playback device for my Modplayer. I will also write in full support for this device in Sound Studio 4.0 (commercial), as well as any other digital sound programs I happen to write later. The MAX505 chip will also be used in another board I am designing, called the E-8 (Enhanced-8) board. This board will use two MAX505's to provide an effective output resolution of 16 bits per channel. The board will also feature a pair of National Semiconductor ADC0820BCN chips, for sampling in 8 bit two channel stereo (Unless I find a better chip to use). No release date or pricing has been set for this board as of yet. -- For more information on this or general commentary, you may reach Nate at the following addresses: Dannenberg Concepts, Ltd. "Bringing your Commodore 128 one step closer!" Email: tron@wichita.fn.net Phone: (316) 777-0248 Snail: Dannenberg Concepts, Ltd. c/o Mr. Nate Dannenberg 306 S. 1st Ave Mulvane, KS 67110 FidoNet: 1:291/25 Groups: CBM, CBM-128, and CBM-GEOS Usenet: comp.sys.cbm, alt.binaries.sounds.mods \H03:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Upgrading your C128's VDC memory to 64K by Mike Gordillo This will be a quick "how-to" on upgrading your VDC memory from 16K to 64K. Those of you who have C128-DCR's should already have this upgrade from the factory, but those who own original flat C128's or original C128D's may wish to undertake the following VDC ram expansion. First off, the last time I checked, you needed two 64x4 DRAM's and the prices for such ram chips were as follows: LA Trade - 1-800-433-3726 64x4 DRAM - 80 nanoseconds = $3.75 Nevada Computer - 1-800-982-2925 64x4 DRAM - 100 nanoseconds = $2.45 COMP-USA !!! 1-800-COMP-USA 64x4 DRAM - 100 nanoseconds = $1.50 ! ! ! ! The instructions for installing them into your machine quite simple. Just open up your C-128, remove the shielding, keyboard connector, etc. You should now see a metallic box around the center of the C-128's motherboard. Remove the lid on that box with the keyboard facing you, revealing the following: >>>>>>> Back of C-128 <<<<<<< ---**--- ------ / - - - LC - / - 8 - - - / - 5 - - - / VDC - 6 - --**-- / VIC Chip Chip - 3 - / Circuitry - - ------ ------ / to the right - V - - 16 - - 16 - / - D - - x - - x - / - C - - 4 - - 4 - / - - - - - - / <---These two 16x4 DRAM's - - -DRAM- -DRAM- / are to be replaced with -------- --**-- --**-- / 64x4 DRAM's. ** = designates the directional notch on the chip >>>>>>> Front of C-128 <<<<<<< In your machine you will see two 16 by 4 DRAM chips (16 kbytes total). Your task is to replace them with 64 by 4 DRAM chips (64 kbytes total) that you can get cheaply at CompUsa for example :)...no minimum order.. :)). The hard part is now at hand. The 16 by 4 chips are not on stacks! This means you have to unsolder them. If you have never played with a soldering iron before this is going to be a BIG pain in the rear and you may damage your C-128 in the process. (See, isn't it neat to find out for FREE instead o paying Slick Wile up front?) If you have some experience with a soldering iron, remove the C-128's mother board from the case, flip it over, and find the pins for the 16 by 4 DRAMs on the back. Unsolder them and remove the chips. Solder the 64 by 4 DRAM chips in the same exact spots as the 16 by 4 chips, remembering to keep the notch on the 64 by 4 chip facing the notch on the original 16 by 4 chip. Solder in stacks/sockets first, and then plug in the 64 by 4 chips, because it is safer to solder in the sockets AND if a memory chip goes bad, you won't have to unsolder again (just pop out the ram chip from its socket.) 18-Pin Stacks/Sockets are 50 cents each at Radio Shack. DISCLAIMER : You undertake this procedure at your own risk. If you destroy your machine, its your cross to bear. I did this to a C-128 last Sunday. It took 2 hours with the simple soldering tools I have. It may take you less time or more time depending on your equipment and experience. DRAMs are a pain to remove in any case. I sped up removal by just cutting the legs on the original 16 by 4 chips with a manicurist's scissors. Definitions : 16 by 4 (16 x 4) = 8 Kbytes of memory 64 by 4 (64 x 4) = 32 Kbytes of memory DRAM = Dynamic Random Access Memory 8563 VDC = The C-128's 80 column video chip. LC = Logic chip next to VDC, more specifically, its a 74LS244. Specific labelling on the original 16 by 4 DRAM: You should either see TMS4416 on them or MB81416. They are usually 120 nanosecond chips, so you must buy 64 by 4 chips that are at least 120 nano- second variety. I chose 100 nanoseconds because it was the least expensive 64 by 4 DRAM speed that I could find. -- For general comments on this article, feel free to contact Mike Gordillo at s0621126@dominic.barry.edu \H04:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: >> The Metal Shop --- *+* --- with SMS Mike Eglestone << of Diamondback BBS (305)258-5039 Senior Master Sergeant Mike Eglestone has been a devout C= Hardware guru for over ten years and is the Sysop of one of the most active BBS's on the Commnet Commodore BBS network. Mr. Eglestone has written for illustrious magazines in the Commodore 8 bit community such as dieHard magazine and the very distinguished Commodore World. We are pleased to have him entertain our questions pertaining to hardware repair. As always, neither the editors, the staff of disC=overy, nor Mr. Eglestone are responsible for the use or misuse of any information presented in this article. -- >> Dear SMS Mike, >> >> My CMD Hard Drive refuses to undergo its power-up sequence at irregular >> intervals and is belching out a whole series of errors and bad blocks. >> Unfortunately, my drive is long past its warranty period and I have no >> idea what is wrong with it. What do you think? >> >> MG MG, First of all, I would give CMD a call about this even if your drive is out of warranty. They know their drives better than anyone, but with that said, I have run into a total of 5 (was 4) Hard Drives produced by CMD that had cold solder joints on the main circuit board. They were discovered at the connection point for the Power Supply, and were all on the 12VDC connectors for the drive motor. There is a 4 pin DIN plug attached to the main circuit board which is the plug for the power supply to the drive. The connection on the bottom of the board (remove it and turn it over) has a tendency to be bad or loose from poor solder joints (cold joints). This cold or loose joint will cause strange problems with the drive motor, and you will notice SCSI errors, or a sudden accumulation of Bad Blocks. It can even result in the complete failure of the drive to start up, or it might just shut down (stop turning) without warning. The solution is very simple. Remove the drive and circuit board. Turn the board over, and re-solder the joints. Takes about 15 minutes from start to finish... The way the main circuit board is attached to the case is one of the problems. The rear support point is in front of the DIN plug but close to an inch away from it. Each time you insert the plug into the DIN connector, it puts pressure on those connection points and BENDS the board slightly. After a while, the connections loosen up at the solder joints. Cold Joints or joints that were just slightly tacked, will crack or just seperate from the foil. I have now fixed 5 drives with this same problem, and they work perfectly again... CMD is aware of the situation, but they think it's an isolated problem with one batch of boards. I don't think so. I think it's going to happen to all of them sooner or later. That rear support and the location of the DIN seem to be a failure point. -- >> Dear SMS Mike, >> >> I am about to throw my C128's keyboard out my balcony. For the past >> year, a key has been failing to work properly about once a month. I now >> have to put up with at least 12-15 keys that either refuse to work at all >> or require some deep-felt pounding in order to generate a character. >> >> What can I do about this aside from buying another keyboard?? >> >> SK SK, I have cleaned and restored hundreds of keyboards over the last 10 years. I have piles and piles of boards and board parts (64 and 128) sitting around my computer/repair room. Not to mention around 10 extra mother boards for both types of computer. After playing around with the carbon contacts on both the circuit board itself, and the carbon impregnated (rubber contacts) on the end of the key plungers, I have come to the conclusion that the only cleaner required is de-natured alcohol. It works on every part of the board, and works perfectly. When I do a cleaning job, I remove (strip) every key down to its component parts. The keys themselves go into a bleach solution. The rubber pads and plungers go into a pan of denatured alcohol. The key springs (if not rusted) are lightly sprayed with WD-40 and rinsed with alcolol later. If they are rusted, they go into a solution of phosphoric and dichromate acid. Brand name is OSPHO (any True Value Hardware Store has it). The circuit board itself is washed with de-natured alcohol and lightly dried with a blower. Seldom do the carbon spots on the circuit board go bad. If they do, you can use a product which contains silver loaded epoxy, and mix that with carbon powder; Graphite. There is also a spray carbon compound that's available, but I don't remember the name at the moment. It's used by the aircraft industry. Once, I couldn't find any silver loaded epoxy. I just used a hobby type (two part) epoxy and mixed in huge quanitities of graphite. It worked perfectly. Dab on a drop, let it setup, lightly sand the surface to break the glaze.. (wham), a new conductive contacting surface. It was trial and error for a long time, but I now have it down to a science. I normally get four years out of an overhauled keyboard; using original parts and proper cleaning solutions. Oh sure, I have written off a few keyboards as not worth fixing, but that isn't the norm. When one comes in that has been abused to the point that I don't even want to attempt a repair, it becomes parts for other boards. One thing always needs to be done with keyboards (prior to re-assembly). Plug in the circuit board, turn on the computer, then touch each keypad to a contact (one by one) and make sure it's working. This is done by hand. Blank un-assembled (open) circuit board, with keypads held in the fingers. It takes about 5 minutes, and it's well worth the effort involved. NO electrical voltages are present, that will harm you. There are only a couple of volts of DC present, and that is the output of the CIA (Complex Interface Adaptor) which is the Keyboard control chip. You can't run a conditivity test on the rubber keypads with a tester. It's got to have a slight DC voltage present to make it work. A standard VOM will not do the job. The computer itself makes a dandy test bed. -- >> Dear SMS Mike, >> >> Every now and then I'll be sitting peacefully in front of my 128 when >> I start to hear crackling noises out of the monitor's speaker and I'll >> notice that the 40 column screen starts to go wacky on me at the same >> time. Sometimes I'll see color changes and sometimes I'll see little >> random characters appear on screen. The crackling noises appear to always >> be a consistent low pop-pop-click and occur in both 64 and 128 modes. >> A few rare times, 128 mode will crash and hang when these events occur, >> although 64 mode will be a-ok (except for the crackling and popping). >> I know my monitors and cable are working 100% so I am at a loss to explain >> this phenomena. >> >> RR -- RR, There are three possibilities, and one of them is going to sound a bit odd. The 128 uses a two stage video output system. The VIC chip and a seperate Vidio Controller. Both are located inside the metal Box (with lid) in the back left hand side of the circuit board. There is a screw hole dead center of the metal box.. The VIC chip would be my first choice. It's on the right hand side of the box. IC-U21 is the number on the board. The Vidio Controller is mostly for RGB displays and 80 col memory enhancement, but it does work WITH the VIC chip in some area of Composite color IC-U22 (Left hand side of the box). Here is the "odd" choice, but one that I have found in quite a few 128 video and "Crackling Sound" problems.. -> The ON/OFF switch for the 128 itself. As you are aware, the 64 and 128 use a dual voltage power supply system. The computer has the second stage on the Circuit board. That On/Off switch can become dirty inside, or limited in movement enough so that it doesn't make contact perfectly in the ON position. Sometimes it's just a matter of flipping the switch on HARD to make good contact, and sometimes it's necessary to actually remove the switch and clean the contacts internally. On 6 different 128's, where I have come across this problem, I have had to remove the circuit board and File out the switch Hole "larger" at the top because the computer CASE itself was interfearing with the movement of the switch. A "not quite closed" contact in that switch will cause the 9VAC section to ARC slightly. This will drop colors and cause the sound you were talking about. It will affect your internal clocking and cause both video and audio problems. It's always best to check the IC's by substitution. Take a known good IC and replace the one in use. If that doesn't solve the problem then do the same thing with the other chip. Sometimes, just pulling the chip out and putting it back in will fix contact problems. Humidity will cause minor corrosion on the legs of an IC over a period of time. Re-seating the IC will normally fix this sort of thing. A quick shot of contact cleaner in the IC socket never hurts. Those are your three choices guy. Well, there is ONE more, but it's a remote possibility. The DIN socket on the composite video OUT side. You can give that socket a shot of contact cleaner and see if the problem clears up. It will sometimes build up a slight film and cause similar problems to the one you are talking about. Last thing. If you remove the RF shield (the metal cover over the circuit board) LEAVE it OFF. The computer will run cooler and you really don't need that hunk of metal. I normally throw the darn things away. Although it is used as an RF shield and a heat sink, it causes more problems than it solves. SMS MIKE -- Mr. Mike Eglestone may be reached for questions or comments at Diamondback BBS (305)258-5039 or through the editors of disC=overy. \END:::::::d:i:s:C=:o:v:e:r:y:::::::::::::::::i:s:s:u:e::1:::::::::::::::::::: :::::::::::::::::::::::::::::::May 17, 1996:::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::