SAMPLE of FIRST BOOK OF KIM This book, by Jim Butterfield and Stan Ockers, was published in 1977 presented useful applications of the KIM-1 module. (Tutorial part 1: pages 6-8 of First Book of KIM). A BEGINNER'S GUIDE TO KIM PROGRAMMING. (Jim Butterfield) Running programs can be fun. But writing programs can be even more fun - and exasperating, and exhilarating, too! When you get the hang of it - and it will take time - you'll be able to create your own games, diversions, or useful routines. This section tries to introduce you to the mechanics of programming, so you can find your own way at your own speed. Don't be afraid to use ideas from other parts of this book. If you like, try changing parts of a program or two and see what happens. And you can borrow whole sections of coding from another program if it does something you want. LOOKING AT MEMORY Random Access Memory. If you've just turned your KIM system on, press the RS (Reset) button to get things started. Hit the following keys: AD (for ADDRESS) 0 0 0 0. You've just entered the address of memory cell 0000, the lowest numbered one in memory. The display will show 0000 (the number you entered) on the left. On the right, you'll nee the contents of cell 0000: it will be a two digit number. That number might be anything to start with; let's change it. Press key DA (for DATA). Now you're ready to change the contents of cell 0000. Key in 44, for example, and you'll see that the cell contents have changed to 44. Hit the + button, and KIM will go to the next address. As you might have guessed, the address following 0000 is 0001. You're still in DATA mode (you hit the DA key, remember?), so you can change the contents of this cell. This time, put in your lucky number, if you have one. Check to see that it shows on the right hand part of the display. This kind of memory - the kind you can put information into - is called RAM, which stands for Random Access Memory. Random access means this: you can go to any part of memory you like, directly, without having to start at the lowest address and working your way through. Check this by going straight up to address 0123 and looking at its contents (key AD 0 1 2 3), then address O000 (key AD O O O 0), which should still contain the value 44 that we put there. Hexadecimal Numbers Now that you're back at address 0000, let's step through several locations using the + key. Don't worry about contents too much. 0001 will still contain your lucky number, of course, but keep stepping with the + key until you reach 0009. What will the next address be? Most people would think that the next number should be 0010, and that would be correct if KIM used the familiar decimal numbering scheme. But KIM still has six more digits to go past 9, because it uses a computer numbering scheme called Hexadecimal. Hit the + key and you'll see address 000A come up. Don't let the alphabetic confuse you - to KIM, A is just the digit that comes after 9. And there are more digits to come. Keep pressing the + button and you'll see that A is followed by B, C, D, E and F. Finally, after address 000F, you'll see address 0010 appear. A word about pronunciation: don't call address 0010 "ten"; say "one zero" instead. After all, it isn't the tenth value after 0000, it's really the sixteenth (the word Hexadecimal means: based on sixteen). If you don't understand why the letters appear, don't worry about it too much. Just understand, for the moment, that the alphabetics represent genuine numbers. So if you're asked to look at address O1ED, you'll know that it's a legitimate address number like any other. And if you're told to store a value of FA in there, go right ahead - you're just putting a number into memory. When you get time, you'll find lots of books that explain Hexadecimal numbering in detail. There's even an appendix in your 6502 Programming Manual on the subject. It makes important and worth-while reading. But for now, just recognize that although the numbers may look a little funny, they are still exactly that: numbers Read Only Memory So far, we've talked about one kind of memory, called RAM. You recall that we said that you can store numbers into RAM. There's another kind of memory in KIM, but you can't store numbers there. It's called ROM, for Read Only Memory. This kind of memory contains fixed values that cannot be changed . For example, let's look at address 1C3A (key AD 1 C 3 A). You'll see the value 18, and that value never changes. Try it: press DA 6 6 to try to change the contents to 66. See how it won't work? ROM contains pre-stored programs which do important things like lighting the display, detecting keyboard input, and reading or writing your cassette tape. These programs are called the Monitor. In fact, the name RIM stands for Keyboard Input Monitor in recognition of the importance of these programs. We'll talk briefly about the Monitor programs later. Special Memory Locations. A few addresses in KIM are connected to things that aren't really memory at all. You can read up on them in the KIM User Manual when you're ready; we'll just point out a few examples here. If you try to store a number into address 1700, for example, you might find that instead of storing the value, KIM will convert it to voltages and deliver these voltages to certain pins on your Application Connector at the edge of the board! Another example: address 1704 connects to a very fast timer - look at that address and you'll see "time going by" as a blur! From this point, find your own way through the last two instructions. Don't bother about the BRK (Break); it just stops the program. As the two registers are stored, you'll want to check that the memory addresses have been changed as expected. Summary The most important things that you've learned about coding are: --the BRK (code 00) command stops the program --the SST switch causes a single instruction to be executed --the internal registers can be viewed. BUT YOU MUST SET YOUR VECTORS PROPERLY (see the beginning of this section) OR NONE OF THE ABOVE WILL WORK! A complete list of the register image addresses can be found in the KIM User Guide on page 39, Fig. 3-13 - when you need it. >From here on, you don't have to take anybody's word for any KIM operation. You can go to your KIM, set SST, and try it for yourself. Exercises 1. Can you change the program so that it swaps the contents of locations 0020 and 00217 2. Billy Beginner wrote the following program to swap the contents of locations 0010 and 0011: 0200 A5 10 START LDA 10 put 0010 into A 0202 85 11 STA 11 store A to 0011 0204 A6 11 LDX 11 put 0011 into X 0206 86 10 STX 10 store X to 0010 0208 00 BRK stop It didn't work. Can you see why? 3. Can you write a program to take the contents of address 0010 and place the same value in locations 0011, 0012, and 0013? (end Tutorial part 2) (Tutorial part 3 of 5: pages 14-15 of First Book of KIM). MINI-PROGRAM B: Setting many locations to zero Here's the program: 0200 A9 00 START LDA #0 value 0 into A 0202 A2 09 LDX #9 start X at 9 0204 95 30 LOOP STA 30,X zero into 0030+X 0206 CA DEX decrease X by 1 0207 10 FB BPL LOOP back if X positive 0209 00 BRK stop the program This program, when you load and run it, will set the value of the ten locations from 0030 to 0039 to zero. We can't give you a whole programming course here Hopefully, you'll use the Programming Manual and the single-step feature to trace out exactly what the program does. But here are a few highlights: When we load registers A and X in the first two instructions, we don't want to load the contents of a memory location. Instead, we want the actual values 0 and 9. To do this, we use a new kind of addressing called IMMEDIATE addressing. Immediate addressing, when we use it, says "Don't go to memory; use this value." Immediate addressing can be spotted two ways. First, note the # sign that we use in writing the program: that signals that we are using immediate mode addressing. Secondly, you may have noticed that the computer instruction (called the Op Code) has changed: the previous program used code A5 to mean LDA; now we're using A9, which also means LDA hut signals immediate addressing. You can - and should - use the SST feature to check that immediate addressing works as advertised The instruction at 0204 uses the X register for INDEXING. That means that instead oŁ storing the A value in address 30, the computer first calculates an effective address by adding the contents of the X register to the "base address" of 30. Since X contains 9 the first time through, the effective address will he 30+9 or 39 - and that's where we store our A value of 00. Later, X will be decreased to a value of 8, so we'll store into address 38. Indexing seems complicated, but remember that it's a very powerful feature of KIM. Try to get the hang of it; it's well worth the effort. The DEX instruction (Op Code CA) is the one that decreases X from 9 to 8 (and later to 7, 6, S and so on). Eventually, as this part of the program is automatically repeated, X will reach a value of 00. Finally, when we decrement X one more time, X will go to value FF, which KIM "sees" as a negative number, kind of like the value -1. KIM views all values in the range 80 to FF as negative - when you're ready, the Programming Manual will tell you more. The BPL instruction at line 0207 is a CONDITIONAL TEST. BPL means Branch Plus. If the result of our previous operation (Decrement X) gives us a positive, or plus, number, we will branch back to address 0204 and repeat the instructions from that point. The X values of 9, 8, 7 ..~, down through O are all positive or plus; so each time we'll go back and set one more location in memory to value zero. Finally, X becomes equal to value FF - a negative number. So in this case, BPL won't branch: the "plus" or "positive" condition isn't satisfied. This last time, since BPL doesn't take us back, we proceed to the following instruction, BRK, which stops the program. That's OX because we've done our job of setting addresses 0030-0039 to value zero Single step the program carefully, checking the value of X from time to time (location 00F5, remember?). Satisfy yourself that you can see it working. By the way, that funny address on the branch instruction (F0) is a special kind of addressing mode called RELATIVE addressing. All branches use it: it's worth reading up on. Exercises 1. Can you change the program to place value 55 in the above locations? 2. Can you change the program to place value 00 in locations 0030 to 0037? 3. Can you change the program to place value FF in locations 00A0 to 00BF? (end Tutorial part 3 of 5) (Tutorial part 4 of 5: pages 19-20 of First Book of KIM). INTERLUDE - PROGRAM TESTING You've met one very powerful tool for checking out programs - the Single Step mode of operation. Let's review it and talk about a few others. The SST mode is especially useful because you can pause between instructions and look at memory or registers. The register values are copied into memory locations from 00EF to 00F5, and while they are not real registers, just copies, they are just as good for testing purposes. Not only can you look at them, you can change them to new values. This ability to change A register can be handy in solving the "what if ... " type of question, or shortening testing of a loop. For example, if you are single-stepping through mini-program B and you don't want to go around the loop a full ten times, you might use this trick. Go around a couple of times to get the loop started, and then change X (00F5) to a much lower value, say 1 or 2. Go back to single-stepping. A couple more turns around the loop, and you're out. Using this method, you won't have set the whole ten locations to zero, of course. But you will see that the loop itself is working right. The Inserted BRK (Break) Sometimes SST seems slow. You might have a long program, and you're sure that the first part is working. What you want is a way to run directly through the first bit, and then stop and single-step the rest. It's not hard. Decide where you want the program to stop, so you can start single-stepping. Then put a RRK command, code 00, at that point. You'll have to wipe out a live instruction, of course, but that's OK. You can put it back after the halt has happened. Let's try doing that on mini-program B. Let's say we want to run straight through to the BPL instruction at 0207, and then single-step from that point on. Change 0207 (previously 10) to value 00, the BRK command. Now go to the beginning of the program (0200); be sure SST is off, and hit GO. You'll see 0209 00 on the display, which tells you that the halt at 0207 has worked. Now go back to 0207, put the value of 10 (for BPL) back in, set the SST switch on, and you're ready to step. Easy? You bet - and you can save lots of time this way in testing big programs. No Operation (NOP, code EA) It sounds funny, but a very handy instruction is one that doesn't do anything. When the microprocessor encounters Op Code EA (NOP), it does nothing - just passes on to the next instruction. The biggest use of the NOP instruction is to take out another instruction that you don't want any more; or to leave room in the coding to add another instruction later if you need to. Some programmers write their programs in sections, and at first they put a BRK instruction between each section. That way, when they are testing, the program will stop after each part, and they can check to see that each part runs OK. When they are finished testing, they change the BRK's to NOP's and the program will run straight through. The ST (Stop) Key When everything is under control in program testing, you won't need the ST key. But sometimes the program 'gets away' on you - and the only way to find out what it's doing is to use this key. Let's wreck mini-program B by wiping out the DEX instruction. We'll do this by replacing it with a NOP so write value EA into location 0206. What will happen? When we run the program, the X register will never change from its starting value oŁ 9 because we don't have a DEX instruction. So the program will keep branching back to LOOP forever, and it will never stop. We've created this situation artificially, of course, but it could have happened by oversight when we were writing the program. Set address 0200, SST off, and hit GO. Everything goes dead. Our program is running but it will never stop. Meanwhile, the display is dark. This time we know why it's happening. But if we didn't, how would we solve it? Press ST - stop - and the computer will freeze. The display will light showing the next instruction we were about to execute. If we wanted to pinpoint the trouble, we could flip over to SST now and track the problem down, step by step. A last comment on the ST button: If the display goes dark and pressing ST doesn't relight it, the computer has a different problem. It has gone berserk due to a completely illegal Op Code. Press the RS (Reset) button now you'll need to start over and use the BRK and SST features to track down the trouble, MINI-PROGRAM C: Displaying values KIM has a 6-digit display. You can show information on the display quite easily, if you know how. In the KIM Monitor programs there are several packages called subroutines that you can call upon to do certain jobs. You could write the same coding for these jobs yourself; but use the monitor subroutines to save time and trouble. When you give the command JSR SCANDS (coded 20 1F 1F), the Monitor will briefly light the display with the data it finds in addresses 00FB, 00FA, and 00F9. That's three locations, each displaying as two digits, so the full six-digit display is filled. "Briefly" means exactly that. The display lights for a split second. To get a steady display, you must repeat the JSR SCANDS command over and over again. Use a loop, of course; no point in filling up your program with JSR SCANDS instructions. You should also know that when you call this Monitor subroutine, the contents of your registers are wiped out. So if you have something important in the A register that you will want to use after giving JSR SCANDS, be sure to put it safely somewhere in memory or you'll lose it. The same goes for other registers such as X and Y. Here's a simple program to show 0000 00 on the display. Note that we must put the value 00 into addresses FB, FA, and F9 before we call JSR SCANDS 0200 A9 00 START LDA #0 zero into A 0202 85 PB STA POINTH first 2 digits 0204 85 FA STA POINTL next 2 digits 0206 85 F9 STA INH last 2 digits 0208 20 1F 1F LOOP JSR SCANDS light up! 020B 4C 08 02 JMP LOOP do it again This program never ends, so eventually you'll have to stop it with the RS or ST keys. See how the last instruction jumps back to address 0208 so the display is lit continuously? Another interesting point: see how the jump address at 020B is "backwards" - 08 02 instead of 0208? This is called "low order first" addressing and you'll see a lot of it on the KIM system. The single-step feature doesn't work too well on Monitor subroutines. That's normal, and it's not serious. These subroutines are well tested and dependable, so you shouldn't need to use SST with them. Exercises l. Can you change the program to make the display show 5555 55? 2. Can you write a program to make the display show 1234 56? 3, How about a program to show the word EFFACE? or FACADE? or COOCOO? (end Tutorial part 4 of 5) (Tutorial part 5 of 5: pages 21-22 of First Book of KIM). MINI-PROGRAM D: Reading the Keypad To read the KIM pushbuttons you have another Monitor subroutine called GETKEY. You "call" it with JSR GETKEY (20 6A 1F). This subroutine will give you the identity of the key that is being pressed at that moment as a value in the A register. You can continue by using this value any way you want. If no key is being pressed at the time, you'll get a value of 15 in A. There are a couple of cautions on the use of JSR GETKEY. First, you must not be in Decimal Mode. If you're not sure about this, give a CLD (D8) instruction at the beginning of your program. Secondly, before giving JSR GETKEY, you must "open up the channel" from the keyboard with either one of two subroutines: JSR SCANDS or JSR KEYIN. You've met JSR SCANDS before: it's used to light the display. If you don't want to light the display, use JSR KEYIN (20 40 1F) before using JSR GETKEY. This program reads the keyboard and displays what it sees: 0200 D8 START CLD clr dc mode 0201 A9 00 LDA #0 zero into A 0203 85 FB STORE STA POINTH 0205 85 FA STA POINTL 0207 85 F9 STA INH 0209 20 1F 1F JSR SCANDS light display 020C 20 6A 1F JSR GETKEY test keys 020F 4C 03 02 JMP STORE Exercises 1. Do you think that the instruction at 0201 is really needed? Try removing it (change 0201 and 0202 to EA) and see. 2. What values do you get for the alphabetic keys? For keys like PC and GO? Are there any keys that don't work with JSR GETKEY? 3. Try running in decimal mode (change 0200 to SED, code F8). What happens? Is it serious? How about key F? 4. Can you change the program so that only the last digit of the display changes with the keyboard? CONCLUSION You've reached the end of our little Beginner's Guide. But you've only started on the road towards understanding programming. Use the tools we have given you here to forge your own path. KIM is a very rich machine. You have 56 Op Codes to choose from, and many powerful addressing combinations. You don't need to learn them all right away, hut when you need them, they'll be there. The KIM Programming Manual makes good reading. Don't try to go through the whole thing at one sitting. Stop and try a few things; you have the Single Step feature to help you understand what each instruction really does. Try leafing through - or stepping through - other people's programs, to understand what makes them tick. Change the coding, if you like, to see what happens. When you see a program that does something you want to do, borrow the coding - you don't need to re-invent the wheel. Don't be discouraged when your program doesn't work on the first try. Even experts have to spend time getting the "bugs" out of their coding. It's part of the game: Think of yourself as Sherlock Holmes, methodically tracking down the elusive villains. A proverb says that a journey of a thousand miles starts with the first step. In the same way, the biggest programs still operate one step at a time. So forge ahead at your own speed. Communicate with other KIM owners; you'll have a lot of information to swap. But most of all: have fun, (end Tutorial part 5 of 5) LUNAR LANDER Jim Butterfield Description This program starts at 0200. When started, you will find yourself at 4500 feet and falling. The thrust on your machine is set to low; so you will pick up speed due to the force of gravity. You can look at your fuel at any time by pressing the "F" button. Your fuel (initially 800 pounds) will be shown in the first four digits of the KIM display. The first two digits of the KIM display always show your rate of ascent of descent. "A" restores altitude. Set your thrust by pressing buttons 1 through 9. Warning: button 0 turns you motor off, and it will not reignite! A thrust of 1, minimum, burns very little fuel; but gravity will be pulling your craft down faster and faster. A thrust of 9, maximum, overcomes gravity and reduces your rate of descent very sharply A thrust of 5 exactly counterbalances gravity; you will continue to descend (or ascend) at a constant rate. If you run out of fuel, your thrust controls will become inoperative. Suggestions for a safe flight: [1] Conserve fuel at the beginning by pressing 1. You begin to pick up speed downwards. [2] When your rate of descent gets up to the 90's, you're falling fast enough. Press 5 to steady the rate. [3] When your altitude reaches about 1500 feet, you'll need to slow down. Press 9 and slow down fast. [4] When your rate of descent has dropped to 15 or 20, steady the craft by pressing 5 or 6. Now you're on your own. ; main routine - initialize 0200 A2 0D GO LDX #13 Fourteen bytes 0202 BD CC 02 LP1 LDA INIT,X 0205 95 D5 STA ALT,X 0207 CA DEX 0208 10 F8 BPL LP1 ; Update height and velocity 020A A2 05 CALC LDX #5 020C A0 01 RECAL LDY #1 020E F8 SED 020F 18 CLC ----- 0210 B5 D5 LDA ALT,X 0212 75 D7 ADC ALT+2,X add each digit 0214 95 D5 STA ALT,X 0216 CA DEX 0217 88 DEY 0218 10 F6 BPL RECAL next digit 021A B5 D8 LDA ALT+3,X hi-order .. zero .. 021C 10 02 BPL INCR .. or .. 021E A9 99 LDA #$99 0220 75 D5 INCR ADC ALT,X 0222 95 D5 STA ALT,X 0224 CA DEX 0225 10 E5 BPL RECAL next addition 0227 A5 D5 LDA ALT 0229 10 0D BPL UP still flying? 022B A9 00 LDA #0 022D 85 E2 STA DOWN 022F A2 02 LDX #2 0231 95 D5 DD STA ALT,X 0233 95 DB STA TH2,X 0235 CA DEX 0236 10 F9 BPL DD 0238 38 UP SEC update fuel 0239 A5 E0 LDA FUEL+2 023B E5 DD SBC THRUST 023D 85 E0 STA FUEL+2 023F A2 01 LDX #1 two more digits to go 0241 B5 DE LP2 LDA FUEL,X 0243 E9 00 SBC #0 0245 95 DE STA FUEL,X 0247 CA DEX 0248 10 F7 BPL LP2 024A B0 0C BCS TANK still got fuel? 024C A9 00 LDA #0 024E A2 03 LDX #3 0250 95 DD LP3 STA THRUST,X 0252 CA DEX 0253 10 FB BPL LP3 ; show alt, fuel, or messages 0255 20 BD 02 JSR THHRUST 0258 A5 DE TANK LDA FUEL fuel into registers 025A A6 DF LDX FUEL+1 025C 09 F0 ORA #$F0 PLUS f FLAG 025E A4 E1 LDY MODE 0260 F0 20 BEQ ST 0262 F0 9C GOLINK BEQ GO 0264 F0 A4 CLINK BEQ CALC 0266 A2 FE LDX #$FE 0268 A0 5A LDY #$5A 026A 18 CLC 026B A5 D9 LDA VEL+1 026D 69 05 ADC #5 026F A5 D8 LDA VEL 0271 69 00 ADC #0 ------------ 0273 B0 04 BCS GOOD 0275 A2 AD LDX #$AD 0277 A0 DE LDY #$DE 0279 98 GOOD TYA 027A A4 E2 LDY DOWN 027C F0 04 BEQ ST 027E A5 D5 LDA ALT 0280 A6 D6 LDX ALT+1 0282 85 FB ST STA POINTH 0284 86 FA STX PONTL ; show rate of ascent/descent as absolute 0286 A5 D9 LDA VEL+1 0288 A6 D8 LDX VEL up or down? 028A 10 05 BPL FLY .. up, we're OK 028C 38 SEC 028D A9 00 LDA #0 028F E5 D9 SBC VEL+1 0291 85 F9 FLY STA INH 0293 A9 02 LDA #2 0295 85 E3 STA DECK 0297 D8 FLITE CLD DISPLAY & KEY TEST 0298 20 1F 1F JSR SCANDS light 'em up! 029B 20 6A 1F JSR GETKEY check keys 029E C9 13 CMP #$13 GO key? 02A0 F0 C0 BEQ GOLINK ...yes 02A2 B0 03 BCS NOKEY .. if no key 02A4 20 AD 02 JSR DOKEY 02A7 C6 E3 NOKEY DEC DECK 02A9 D0 ED BNE FLITE 02AB F0 B7 BEQ CLINK to CALC ; calculat accel as thrust minus 5 02AD C9 0A DOKEY CMP #$0A test numeric 02AF 90 05 BCC NUMBER 02B1 49 0F EOR #$0F fuel gives 0 flag 02B3 85 E1 STA MODE 02B5 60 RETRN RTS 02B6 AA NUMBER TAX 02B7 A5 DD LDA THRUST test: is motor off? 02B9 F0 FA BEQ RETRN yes, ignore key 02BB 86 DD STA THRUST no, store thrust ; calculate accel as thrust minus 5 02BD A5 DD THRSET LDA THRUST 02BF 38 SEC 02C0 F8 SED 02C1 E9 05 SBC #5 02C3 85 DC STA TH2+1 02C5 A9 00 LDA #0 02C7 E9 00 SBC #0 02C9 85 DB STA TH2 02CB 60 RTS ; initial values 02CC 45 01 00 .BYTE $R5,1,0 altitude 02CF 99 81 00 .BYTE $99,$81,0 rate of ascent 02D2 99 97 .BYTE $99,$97 acceleration 02D4 02 .BYTE 2 thrust 02D5 08 00 00 .BYTE 8,0,0 fuel 02D8 01 .BYTE 1 display mode 02D9 01 .BYTE 1 in flight/landed *=$00D5 00D5 ALT *=*+3 00D8 VEL *=*+3 00DB TH2 *=*+2 00DD THRUST *=*+1 00DE FUEL *=*+1 00E1 MODE *=*+1 00E2 DOWN *=*+1 00E3 DECK *=*+1 ; linkages to KIM monitor SCANDS = $1F1F GETKEY = $1F6A POINTH = $FB POINTL = $FA INH = $F9 ***** Hex Dump - Lunar Lander ***** 0200 A2 0D BD CC 02 95 D5 CA 10 F8 A2 05 A0 01 F8 18 0210 B5 D5 75 D7 95 D5 CA 88 10 F6 B5 D8 10 02 A9 99 0220 75 D5 95 D5 CA 10 E5 A5 D5 10 0D A9 00 85 E2 A2 0230 02 95 D5 95 DB CA 10 F9 38 A5 E0 E5 DD 85 E0 A2 0240 01 B5 DE E9 00 95 DE CA 10 F7 B0 0C A9 00 A2 03 0250 95 DD CA 10 FB 20 BD 02 A5 DE A6 DF 09 F0 A4 E1 0260 F0 20 F0 9C F0 A4 A2 FE A0 5A 18 A5 D9 69 05 A5 0270 D8 69 00 B0 04 A2 AD A0 DE 98 A4 E2 F0 04 A5 D5 0280 A6 D6 85 FB 86 FA A5 D9 A6 D8 10 05 38 A9 00 E5 0290 D9 85 F9 A9 02 85 E3 D8 20 1F 1F 20 6A 1F C9 13 02A0 F0 C0 B0 03 20 AD 02 C6 E3 D0 ED F0 B7 C9 0A 90 02B0 05 49 0F 85 E1 60 AA A5 DD F0 FA 86 DD A5 DD 38 02C0 F8 E9 05 85 DC A9 00 E9 00 85 DB 60 45 01 00 99 02D0 81 00 99 97 02 08 00 00 01 01 ----------------------------------------------------------- MUSIC BOX Jim Butterfield DESCRIPTION This program plays one or several tunes via the "audio out" interface of KIM-l; use the same connection as that for recording on cassette tape. If your tape recorder has a ~monitor~ feature, you can listen to the tune as well as record it. Alternatively, an amplifier will play the signal through a speaker. HOW TO RUN Load the program; load the tune(s) either from cassette tape, paper tape, or keyboard entry. Be sure to store the value fa at the end of each tune, and behind the last tune, store: FF 00~ Starting address for the program is 200; enter ad 0 2 0 0 GO. HOW TO WRITE YOUR OWN TUNE(S) Each note goes into a byte of storage, starting at location 0000 of memory. Each tune should end with the value FA which stops the program until GO is pressed. Special codes are incorporated in the program to allow certain effects - adjustment of speed, tone, etc. The codes are followed by a value which sets the particular effect. Codes are listed below: CODE EFFECT INITIALLY EXAMPLES FB Sets speed of tune $30 18 is quick; 60 is slow FC Sets length of 02 2 means, "Long note lasts "long" notes twice as long as short" FD Sets octave (pitch) 01 2 is bass; 4 is deep bass. FE Sets instrument $FF FF is piano; 00 is clarinet FF Sets address for 00 00 will take you back to tune first tune; like a "jump" For example, at any time during a tune, you may insert the sequence FB 18 and the tune will then begin to play at fast speed. Inserting FF 45 will cause a switch to the tune at address 45. The initial values shown can be reset at any time by starting at address 200. No tune should extend beyond address DF, since program values are stored at E0 and up. The program can be easily converted to a subroutine (by replacing the BRK instruction with a RTS). This allows the programmer to play various "phrases" of music to produce quite complex tunes. [Table of notes from page 92, to help write your own music, not yet included] [Pages 92 and 93, containing the program listing, now reinserted here]. ***** Fixed locations for MUSIC BOX ***** WORK = $E0 LIMIT = $E6 VAL2 = $E9 VAL1 = $EA TIMER = $EB XSAV = $EC SBD = $1742 PBDD = $1743 *= $0200 ; PROGRAM - MUSIC BOX 0200 A2 05 START LDX #5 0202 BD 86 02 LP1 LDA INIT,X 0205 95 E0 STA WORK,X 0207 CA DEX 0208 10 F8 BPL LP1 020A A9 BF GO LDA #$BF 020C 8D 43 17 STA PBDD open output channel 020F A0 00 LDY #0 0211 B1 E4 LDA (WORK+4),Y get next note 0213 E6 E4 INC WORK+4 0215 C9 FA CMP #$FA test for halt 0217 D0 04 BNE NEXT 0219 00 BRK (or RTS if used as subroutine) 021A EA NOP 021B F0 ED BEQ GO resume when GO pressed 021D 90 0B NEXT BCC NOTE is it a note? 021F E9 FB SBC #$FB if not, decode instrument 0221 AA TAX and put it into x 0222 B1 E4 LDA (WORK+4),Y get parameter 0224 E6 E4 INC WORK+4 0226 95 E0 STA WORK,X store in work table 0228 B0 E0 BCS GO unconditional branch ; Set up for timing note 022A A6 E0 NOTE LDX WORK timing 022C 86 E7 STX LIMIT+1 022E A6 E1 LDX WORK+1 long note factor 0230 A8 TAY test accumulator 0231 30 02 BMI OVER long noteprint 0233 A2 01 LDX #1 nope, set short note 0235 86 E6 OVER STX LIMIT store length factor 0237 29 7F AND #$7F remove short/long flag 0239 85 E9 STA VAL2 023B F0 02 BEQ HUSH is it a pause 023D 85 EA STA VAL1 no, get pitch 023F A5 E9 HUSH LDA VAL2 get iming and.. 0241 25 E3 AND WORK+3 bypass if muted 0243 F0 04 BEQ ON 0245 E6 EA INC VAL1 else fade the 0247 C6 E9 DEC VAL2 note 0249 A6 E9 ON LDX VAL2 024B A9 A7 LDA #$A7 bit 7 on 024D 20 5D 02 JSR SOUND 0250 30 B8 BMI GO 0252 A6 EA LDX VAL1 0254 A9 27 LDA #$27 bit 7 off 0256 20 5D 02 JSR SOUND delay the other half 0259 30 AF BMI GO end of note 025B 10 E2 BPL HUSH no, more cycles ; Subroutine to send a bit 025D A4 E2 SOUND LDY WORK+2 octave flag 025F 84 EB STY TIMER 0261 86 EC STX XSAV bit timing 0263 E0 00 SLOOP CPX #0 end of timing? 0265 D0 08 BNE CONT no, continue 0267 A6 EC LDX XSAV restore timing 0269 C6 EB DEC TIMER in case of .. 026B D0 F6 BNE SLOOP .. anther octave 026D F0 16 BEQ SEX else exit 026F 8D 42 17 CONT STA SBD 0272 CA DEX 0273 C6 E8 DEC LIMIT+2 0275 D0 EC BNE SLOOP 0277 C6 E7 DEC LIMIT+1 0279 D0 E8 BNE SLOOP 027B A4 E0 LDY WORK 027D 84 E7 STY LIMIT+1 027F C6 E6 DEC LIMIT 0281 D0 E0 BNE SLOOP 0283 A9 FF LDA #$FF 0285 60 SEX RTS ; initial constants 0286 30 02 01 INIT .BYTE $30,2,1 0209 FF 00 00 .BYTE $FF,0,0 SAMPLE MUSIC FOR MUSIC BOX PROGRAM 0000 FB 18 FE FF 44 51 E6 E6 66 5A 51 4C C4 C4 C4 D1 0010 BD BD BD 00 44 BD 00 44 3D 36 33 2D A8 80 80 33 0020 44 B3 80 80 44 51 C4 80 80 5A 51 E6 80 80 FA 0020 FE 0030 00 FB 28 5A 5A 51 48 5A 48 D1 5A 5A 51 48 DA E0 0040 5A 5A 51 48 44 48 51 5A 60 79 6C 60 DA DA FA FE 0050 FF 5A 5A 5A 5A 5A 5A 66 72 79 E6 E6 80 00 56 56 0060 56 56 56 56 5A 66 F2 80 80 4C 4B 4C 4C 4C 4C 56 0070 5A 56 4C 00 Ch 44 4C 56 5A 5A 56 5A 66 56 6A 66 0080 F2 80 FE 00 00 72 5A CC 72 5A CC 72 5A CC 80 B8 0090 80 4C 56 5A 56 5A E6 F2 80 FA FF 00 Note that tunes 1 and 2 set both the speed and the instrument. Tune 3 ccntinues at the same speed as the previous one, but the instrument is changed during the tune. The program can be changed to use the speaker shown in figure 5.1 of the kim manual as follows: BYTE INITIALLY CHANGE TO 020D 43 01 024C A7 FF 0255 27 00 0270 42 00 ***** Extra datafile for MUSIC BOX ***** 0000- FE 00 56 52 AD AF AD AF AD FC 06 AF FC 02 FE FF 0010- 2F 29 26 24 2F 29 AA 32 A9 FC 06 AF FC 02 FE 00 0020- 56 52 AD AF 5D AF AD FC 06 AF FC 02 FE FF 39 40 0030- 44 39 2F AF 29 2F 39 A9 B0 80 FE 00 56 52 AD AF 0040- AD AF 0D FC 06 AF FC 02 FE FF 2F 29 26 24 2F 29 0050- AA 32 A9 AF B0 80 2F 29 24 2F 29 A4 2F 29 2F 24 0060- 2F 29 AA 2F 29 2F 2A 2F 29 AQ 32 A9 AF 80 80 FA 0070- FF 00 Note: be sure to set the break vector 17FE,FF (00,1C) BANDIT = Jim Butterfield Start the Program at 0200 and on the right, you'll see the $25 that KIM has given you to play with, The funny symbols on the left are your "wheels" - hit any key and see them spin. Every time you spin the wheels by hitting a key it costs you $1. When the wheels stop, you might have a winning combination, in which case you'll see money being added to your total on the right. Most of the time, you'll get nothing ... but that's the luck of the game. The biggest Jackpot is $15: that's three bars across the display. Other combinations pay off, too; you'll soon learn to recognize the "cherry" symbol, which pays $2 every time it shows in the left hand window. There's no house percentage, so you can go a long time on your beginning $25. The most you can make is $99; and if you run out 6f money, too bad; KIM doesn't give credit. BANDIT MICRO-WARE ASSEMBLER 65XX-1.0 PAGE 01 0010: ; 0020: ; ******************************* 0030: ; ******* ONE ARMED BANDIT ****** 0040: ; ******* BY JIM BUTTERFIELD **** 0050: ; ******************************* 0060: ; 0070: 02D1 WINDOW * $0000 DISPLAY WINDOW 0080: 02D1 AMT * $0005 CASH CACHE 0090: 02D1 ARROW * $0006 0100: 02D1 RWD * $0007 REWARD 0110: 02D1 STALLA * $0008 WATT WHILE 0120: 02D1 TUMBLE * $0009 0130: ; 0140: ; LINKAGES TO KIM 0150: ; 0160: 02D1 KEYIN * $1F40 IS KEY DEPRESSED? 0170: 02D1 PADD * $1741 0180: 02D1 SAD * $1740 0190: 02D1 SBD * $1742 0200: 02D1 TABLE * $IFE7 HEX:7 SEG 0210: ; 0220: ; MAIN PROGRAM 0230: ; 0240: 0200 BANDIT ORG $0200 0250: 0200 A9 25 GO LDAIM $25 GIVE HIM $25 0260: 0202 85 05 STA AMT TO START WITH 0270: 0204 20 BA 02 JSR CVAMT AND SHOW IT TO HIM. 0280: 0207 A9 00 LDAIM $00 RESET ARROW. 0290: 0209 85 06 STA ARROW 0300: ; 0310: ; MAIN DISPLAY LOOP 0320: ; 0330: 020B 20 8D 02 LPA JSR DISPLY DISPLAY UNTIL 0340: 020E D0 FB BNE LPA [GO] IS RELEASED. 0350: 0210 E6 09 ROLL INC TUMBLE RANDOMIZE TUMBLE. 0360: 0212 20 8D 02 JSR DISPLY DISPLAY UNTIL 0370: 0215 F0 F9 BEQ ROLL A KEY 19 HTT. 0380: ; 0390: 0217 A9 03 LDAIM $03 0400: 0219 85 06 STA ARROW 0410: 0210 F8 SED 0420: 021C 38 SEC 0430: 021D A5 05 LDA AMT 0440: 021F E9 01 SBCIM $01 CHARGE ONE BUCK. 0450: 0221 85 05 STA AMT 0460: 0223 20 BA 02 JSR CVAMT CONVERT FOR LED. 0470: 0226 26 09 ROL TUMBLE 0480: ; 0490: 0228 20 8D 02 LPB JSR DISPLY 0500: 022B C6 08 DEC STALLA DISPLAY A WHILE. 0510: 022D D0 F9 BNE LPB 0520: 022F A6 06 LDX ARROW 0530: 0231 A5 09 LDA TUMBLE MAKE A 0540: 0233 29 06 ANDIM $06 RESULT 0550: 0235 09 40 ORAIM $40 0560: ; 0570: 0237 95 01 STAAX WINDOW+01 0580: 0239 46 09 LSR TUMBLE 0590: 023B 46 09 LSR TUMBLE DO ALL 0600: 023D C6 06 DEC ARROW 3 WINDOWS. 0610: 023F D0 E7 BNE LPB 0620: ; 0630: ; ALL WHEELS STOPPED COMPUTE PAYOFF 0640: ; 0650: 0241 A5 04 LDA WINDOW+04 0660: 0243 C5 03 CMP WINDOW+03 CHECK FOR 0670: 0245 D0 37 BNE NOMAT A MATCH. 0680: 0247 C5 02 CMP WINDOW+02 0690: 0249 D0 33 BNE NOMAT 0700: 024B A2 10 LDXIM $10 0710: 024D C9 40 CMPIM $40 PAY $15 FOR 3 BARS 0720: 024F F0 0D BEQ PAY 0730: 0251 A2 0B LDXIM $08 0740: 0253 C9 42 CMPIM $42 PAY $10 FOR 3 UPS 0750: 0255 F0 07 BEQ PAY 0760: 0257 A2 06 LDXIM $06 0770: 0259 C9 44 CMPIM $44 PAY $5 FOR 3 DOWNS 0780: 025B F0 01 BEQ PAY 0790: 025D CA DEX 0800: 0810: ; A WIN!!! PAY AMOUNT IN X 0820: 0830: 025E 86 07 PAY STX RWD HIDE REWARD 0840: 0260 A9 80 PAX LDAIM $80 0850: 0262 85 08 STA STALLA 0860: 0264 20 8D 02 LPC JSR DISPLY DISPLAY 0870: 0267 C6 08 DEC STALLA FOR A HALF 0880: 0269 D0 F9 BNE LPC A WHILE. 0890: 026B C6 07 DEC RWD 0900: 026D F0 9C BEQ LPA 0910: 026F 18 CLC SLOWLY ADD 0920: 0270 F8 SED THE PAYOFF 0930: 0271 A5 05 LDA AMT TO THE AM'T. 0940: 0273 69 01 ADCIM $01 0950: 0275 B0 94 BCS LPA 0960: 0277 85 05 STA AMT 0970: 0279 20 BA 02 JSR CVAMT 0980: 027C D0 E2 BNE PAX 0990: 1000: WHELLS NOT ALL T HE SAME - CHECK FOR SMALL PAYOFF 1010: 1020: 027E A2 03 NOMAT LDXIM $03 1030: 0280 C9 46 CMPIM $46 A CHERRY? 1040: 0282 F0 DA BEQ PAY 1050: 0284 20 8D 02 LOK JSR DISPLY 1060: 0287 A5 05 LDA AMT CAN'T PLAY 1070: 0289 D0 80 BNE LPA WITH NO DOUGH! 1080; 028B F0 F7 BEQ LOK 1090: 1100: 1110: 1120: 1130: DISPLAY SUBROUTINE 1140: 1150: 028D A6 06 DISPLY LDX ARROW 1160: 028F 10 02 BPL INDIS ROLL 1170: 0291 F6 02 OVER INCAX WINDOW+02 THE DRUM 1180: 0293 CA INDIS DEX 1190: 0294 10 FB BPL OVER 1200: 0296 A9 7F LDAIM $7F 1210: 0298 8D 41 17 STA PADD 1220: 029B A0 0B LDYIM $08 1230: 029D A2 04 LDXIM $04 1240: 029F B5 00 LITE LDAAX WINDOW LIGHT 1250: 02A1 8C 42 17 STY SBD ALL THE 1260: 02A4 8D 40 17 STA SAD WINDOWS 1270: 02A7 D8 CLD 1280: 02A8 A9 7F LDAIM $7F 1290: 02AA E9 01 ZIP SBCIM $01 1300: 02AC D0 FC BNE ZIP 1310: 02AE 8D 42 17 STA SBD 1320: 02B1 C8 INY 1330: 02B2 C8 INY 1340: 02B3 CA DEX 1350: 02B4 10 E9 BPL LITE 1360: 02B6 20 40 1F JSR KEYIN 1370: 0289 60 1380: ; 1390 ; AMOUNT CONVERSION 1400: ; 1410: 02BA A5 05 CVAMT LDA AMT 1420: 02BC 29 0F ANDIM $0F TRANSLATE 1430: 02BE AA TAX AMOUNT 1440: 02BF BD E7 1F LDAAX TABLE TO LED 1450: 02C2 85 00 STA WINDOW CODE. 1460: 02C4 A5 05 LDA AMT 1470: 02C6 4A LSRA 1480: 02C7 4A LSRA 1490: 02C8 4A LSRA 1500: 02C9 4A LSRA 1510: 02CA AA TAX 1520: 02CB BD E7 1F LDAAX TABLE 1S30: 02CE 85 01 STA WINDOW+01 1540: 02D0 60 RTS SYMBOL TABLE 3000 30A2 AMT 0005 ARROW 0006 BANDIT 0200 CVAMT 02BA DISPLY 028D GO 0200 INDIS 0293 KEYIN 1F40 LITE 029F LOK 0284 LPA 020B LPB 0228 LPC 0264 NOMAT 027E OVER 0291 PADD 1741 PAX OZ60 PAY 025E ROLL 0210 RWD 0007 SAD 1740 SBD 1742 STALLA O008 TABLE 1FE7 TUMBLE 0009 WlNDOW 0000 ZIP 02AA You'll notlce that the listing for BANDIT looks a llttle lf erent from others in thls book. That's because it's the output of a resident assembler operating in an expanded KIM-1 system. See the section on expansion or a further discussion of assemblers. You mlght like to change the payouts so that there is a house percentage. That way, visitors will eventually run out of money lf they play long enough. This has two posslble advantages: It will teash them the evils oi gambling, and they won't hog your KIM all day playing. BAGELS a game listing for the KIM-1 by Jim Butterfield Directions: The computer has chosen four letters, all of which are A,B,C,D,E, or F. Letters may be repeated -- for example, the computer's "Secret Combination" might be CACF or BBBB. You get ten guesses. Each time you guess, the computer will tell you two things: how many letters are exactly correct (the right letter in the right place); and how many letters are correct but in the wrong position. For example, if the computer's secret combination is CBFB and you guess BAFD, the two numbers will be 1 and 1 (the 'F' matches exactly; the 'B' matches but in the wrong place). These numbers will show on the right-hand side of the display; the code you entered will appear on the left. Make a note of your guesses and the computer's responses. With a little mental work, you should be able to break the code exactly in seven or eight words. A correct guess will produce a response of '4-0'. If you don't guess right in ten moves, the computer will give you the answer. After a correct guess, or after the computer tells you the answer, it will start a new game (with a new secret combination) the instant you touch a new key. 0200 E6 16 GO INC RND+4 randomize 0202 20 40 1F JSR KEYIN 'on' pushbutton delay 0205 D0 F9 BNE GO 0207 D8 CLD 0208 A9 0A NEW LDA #$0A ten guesses/game 020A 85 18 STA COUNT new game starting 020C A9 03 LDA #3 create 4 mystery codes 020E 85 10 STA POINTR 0210 38 RAND SEC one plus... 0211 A5 13 LDA RND+1 ...three previous 0213 65 16 ADC RND+4 random numbers 0215 65 17 ADC RND+5 0217 85 12 STA RND =new random value 0219 A2 04 LDX #4 021B B5 12 RLP LDA RND,X move random numbers over 021D 95 13 STA RND+1,X 021F CA DEX 0220 10 F9 BPL RLP 0222 A6 10 LDX POINTR 0224 A0 C0 LDY #$C0 divide by 6 0226 84 11 STY MOD keeping remainder 0228 A0 06 LDY #6 022A C5 11 SET CMP MOD 022C 90 02 BCC PASS 022E E5 11 SBC MOD 0230 46 11 PASS LSR MOD 0232 88 DEY 0233 D0 F5 BNE SET continues division 0235 18 CLC 0236 69 0A ADC #$0A random value A to F 0238 95 00 STA SECRET,X 023A C6 10 DEC POINTR 023C 10 D2 BPL RAND 023E C6 18 GUESS DEC COUNT new guess starts here 0240 30 7A BMI FINISH ten guesses? 0242 A9 00 LDA #0 0244 A2 0C LDX #$0C clear from WINDOW... 0246 95 04 WIPE STA WINDOW,X ...to POINTR 0248 CA DEX 0249 10 FB BPL WIPE ; ; WAIT FOR KEY TO BE DEPRESSED ; 024B 20 CE 02 WAIT JSR SHOW 024E F0 FB BEQ WAIT 0250 20 CE 02 JSR SHOW 0253 F0 F6 BEQ WAIT debounce key 0255 A5 08 LDA WINDOW+4 new guess? 0257 F0 08 BEQ RESUME no, input digit 0259 29 60 AND #$60 025B 49 60 EOR #$60 previous game finished? 025D F0 A9 BEQ NEW ...yes, new game; 025F D0 DD BNE GUESS ...no, next guess 0261 20 6A 1F ESUME JSR GETKEY 0264 C9 10 CMP #$10 guess must be in 0266 B0 E3 BCS WAIT range A to F 0268 C9 0A CMP #$0A 026A 90 DF BCC WAIT 026C A8 TAY 026D A6 10 LDX POINTR zero to start 026F E6 10 INC POINTR 0271 B9 E7 1F LDA TABLE,Y segment pattern 0274 95 04 STA WINDOW,X 0276 98 TYA 0277 D5 00 CMP SECRET,X exact match? 0279 D0 03 BNE NOTEX 027B E6 0E INC EXACT 027D 8A TXA destroy input 027E 95 0A NOTEX STA INPUT,X 0280 A5 07 LDA WINDOW+3 has fourth digit arrived? 0282 F0 31 BEQ BUTT ...no 0284 A0 03 LDY #3 ...yes, calculate matches 0286 B9 0A 00 STEP LDA INPUT,Y for each digit: 0289 29 18 AND #$18 has it already been 028B F0 12 BEQ ON matched? 028D B9 00 00 LDA SECRET,Y 0290 A2 03 LDX #3 if not, test 0292 D5 0A LOOK CMP INPUT,X ...against input 0294 F0 05 BEQ GOT 0296 CA DEX 0297 10 F9 BPL LOOK 0299 30 04 BMI ON 029B E6 0F GOT INC MATCH increment counter 029D 16 0A ASL INPUT,X and destroy input 029F 88 ON DEY 02A0 10 E4 BPL STEP 02A2 A2 01 LDX #1 display counts 02A4 B4 0E TRANS LDY EXACT,X 02A6 B9 E7 1F LDA TABLE,Y 02A9 95 08 STA WINDOW+4,X 02AB CA DEX 02AC 10 F6 BPL TRANS 02AE 20 CE 02 DELAY JSR SHOW long pause for debounce 02B1 E6 0F INC MATCH 02B3 D0 F9 BNE DELAY 02B5 20 CE 02 BUTT JSR SHOW wait for key release 02B8 D0 FB BNE BUTT 02BA F0 8F BEQ WAIT ; ; TEN GUESSES MADE -- SHOW ANSWER ; 02BC A2 03 FINISH LDX #3 02BE B4 00 FIN2 LDY SECRET,X 02C0 B9 E7 1F LDA TABLE,Y 02C3 95 04 STA WINDOW,X 02C5 CA DEX 02C6 10 F6 BPL FIN2 02C8 A9 E3 LDA #$C3 'square' flag 02CA 85 08 STA WINDOW+4 02CC D0 E0 BNE DELAY unconditional jump ; ; SUBROUTINE TO DISPLAY ; AND TEST KEYBOARD ; 02CE A0 13 SHOW LDY #$13 02D0 A2 05 LDX #5 02D2 A9 7F LDA #$7F 02D4 8D 41 17 STA PADD 02D7 B5 04 LITE LDA WINDOW,X 02D9 8D 40 17 STA SAD 02DC 8C 42 17 STY SBD 02DF E6 11 POZ INC MOD pause loop 02E1 D0 FC BNE POZ 02E3 88 DEY 02E4 88 DEY 02E5 CA DEX 02E6 10 EF BPL LITE 02E8 20 40 1F JSR KEYIN 02EB 60 RTS END Program notes: 1. Program enforces a pause of about 4 seconds after displaying counts or answer. This guards against display being "missed" due to bounce, or hasty keying. 2. After count displayed, or at end of game(s), user can blank display, if desired, by pressing GO or any numeric key. Game operation is not affected, but user may feel it 'separates' games better. 3. When a digit from the user's guess is matched, it is destroyed so that it will not be matched again. There are two significantly different types of 'destruction', however (at 27D and 29D); the test at label STEP is sensitive to which one is used. ; ; LINKAGES TO KIM MONITOR ; KEYIN =$1F40 GETKEY =$1F6A TABLE =$1FE7 PADD =$1741 SBD =$1742 SAD =$1740 ; ; WORK AREAS ; 0000 SECRET *=*+4 computer's secret code 0004 WINDOW *=*+6 display window 000A INPUT *=*+4 player's input area 000E EXACT *=*+1 # of exact matches 000F MATCH *=*+1 # of other matches 0010 POINTR *=*+1 digit being input 0011 MOD *=*+1 divisor/delay flag 0012 RND *=*+6 random number series 0018 COUNT *=*+1 number of guesses left HEX DUMP FOR 'BAGELS' 0200 E6 16 20 40 1F D0 F9 D8 A9 0A 85 18 A9 03 85 10 0210 38 A5 13 65 16 65 17 85 12 A2 04 B5 12 95 13 CA 0220 10 F9 A6 10 A0 C0 84 11 A0 06 C5 11 90 02 E5 11 0230 46 11 88 D0 F5 18 69 0A 95 00 C6 10 10 D2 C6 18 0240 30 7A A9 00 A2 0C 95 04 CA 10 FB 20 CE 02 F0 FB 0250 20 CE 02 F0 F6 A5 08 F0 08 29 60 49 60 F0 A9 D0 0260 DD 20 6A 1F C9 10 B0 E3 C9 0A 90 DF A8 A6 10 E6 0270 10 B9 E7 1F 95 04 98 D5 00 D0 03 E6 0E 8A 95 0A 0280 A5 07 F0 31 A0 03 B9 0A 00 29 18 F0 12 B9 00 00 0290 A2 03 D5 0A F0 05 CA 10 F9 30 04 E6 0F 16 0A 88 02A0 10 E4 A2 01 B4 0E B9 E7 1F 95 08 CA 10 F6 20 CE 02B0 02 E6 0F D0 F9 20 CE 02 D0 FB F0 8F A2 03 B4 00 02C0 B9 E7 1F 95 04 CA 10 F6 A9 E3 85 08 D0 E0 A0 13 02D0 A2 05 A9 7F 8D 41 17 B5 04 8D 40 17 8C 42 17 E6 02E0 11 D0 FC 88 88 CA 10 EF 20 40 1F 60 (5) LABEL TABLE FOR PROGRAM 'BAGELS' Address Label Where used 02B5 BUTT 0282 02B8 0018 COUNT 020A 023E 02AE DELAY 02B3 02CC 000E EXACT 027B 02A4 02BE FIN2 02C6 02BC FINISH 0240 1F6A GETKEY 0261 0200 GO 0205 029B GOT 0294 023E GUESS 025F 000A INPUT 027E 0286 0292 029D ------------------ HYPERTAPE by Jim Butterfield How long does it take you to load a full lK of KIM-1 memory? Over two minutes ? And if you're going for memory expansion, how long will It take you to load your 8K? Twenty minutes? Hold onto your hats. Program HYPERTAPE! will write fully compatible tapes in a fraction of the time. You can load a full 1K in 21 seconds. Fully compatible means this: once you've written a tape using HYPERTAPE! you can read it back in, using the normal KIM-1 program (starting at 1873 as usual). And the utilities and diagnostic programs work on this super-compressed data (e.g., DIRECTORY and VUTAPE). You'll need some memory space for the program, of course. If you have memory expansion, there'll be no problem finding space. But if you're on the basic KIM-1, as I am, you'll have to "squeeze in" HYPERTAPE! along with the programs you're dumping to tape. I try to leave page 1 alone usually (the stack can overwrite your program due to bugs), so I stage HYPERTAPE! in that area. For the convenience of relocation, the listing underlines those addresses that will need changing. [Ed note: the book appears to have missed doing this]. There are also four values needed in page zero which you may change to any convenient location. For those Interested in the theory of the thing, I should mention: HYPERTAPE! is not the limit. If you wished to abandon KIM-1 monitor compatibility, you could continue to speed up tape by a factor of 4 or 5 times more. Can you imagine reading 1K in four seconds? For the moment, however, HYPERTAPE! is plenty fast for me. ; this program also included in Super-dupe 0100 A9 AD DUMP LDA #$AD 0102 8D EC 17 STA VEB 0105 20 32 19 JSR INTVEB set up sub 0108 A9 27 LDA #$27 010A 85 F5 STA GANG flag for SBD 010C A9 BF LDA #$BF 010E 8D 43 17 STA PBDD 0111 A2 64 LDX #$64 0113 A9 16 LDA #$16 0115 20 61 01 JSR HIC ----- 0118 A9 2A LDA #$2A 011A 20 88 01 JSR OUTCHT ----- 011D AD F9 17 LDA ID 0120 20 70 01 JSR OUTST ----- 0123 AD F5 17 LDA SAL 0126 20 6D 01 JSR OUTBTC ----- 0129 AD F6 17 LDA SAH 012C 20 6D 01 JSR OUTBTC ----- 012F 20 EC 17 DUMPT4 JSR VEB 0132 20 6D 01 JSR OUTBTC ----- 0135 20 EA 19 JSR INCVEB 0138 AD ED 17 LDA VEB+1 013B CD F7 17 CMP EAL 013E AD EE 17 LDA VEB+2 0141 ED F8 17 SBC EAH 0144 90 E9 BCC DUMPT4 0146 A9 2F LDA #$2F 0148 20 88 01 JSR OUTCHT ----- 014B AD E7 17 LDA CHKL 014E 20 70 01 JSR OUTBT ----- 0151 AD E8 17 LDA CHKH 0154 20 70 01 EXIT JSR OUTBT ----- 0157 A2 02 LDX #$02 0159 A9 04 LDA #$04 015B 20 61 01 JSR HIC ----- 015E 4C 5C 18 JMP DISPZ ;subroutines 0161 86 F1 HIC STX TIC 0163 48 HIC1 PHA 0164 20 88 01 JSR OUTCHT ----- 0167 68 PLA 0168 C6 F1 DEC TIC 016A D0 F7 BNE HIC1 016C 60 RTS 016D 20 4C 19 OUTBTC JSR CHKT 0170 48 OUTBT PHA 0171 4A LSR A 0172 4A LSR A 0173 4A LSR A 0174 4A LSR A 0175 20 7D 01 JSR HEXOUT ----- 0178 68 PLA 0179 20 7D 01 JSR HEXOUT ----- 017C 60 RTS ; 017D 29 0F HEXOUT AND #$0F 017F C9 0A CMP #$0A 0181 18 CLC 0182 30 02 BMI HEX1 0184 69 07 ADC #$07 0186 69 30 HEX1 ADC #$30 0188 A0 07 OUTCHT LDY #$07 018A 84 F2 STY COUNT 018C A0 02 TRY LDY #$02 018E 84 F3 STY TRIB 0190 BE BE 01 ZON LDX NPUL,Y ----- 0193 48 PHA 0194 2C 47 17 ZON1 BIT CLKRDI 0197 10 FB BPL ZON1 0199 B9 BF 01 LDA TIMG,Y ----- 019C 8D 44 17 STA CLKIT 019F A5 F5 LDA GANG 01A1 49 80 EOR #$80 01A3 8D 42 17 STA SBD 01A6 85 F5 STA GANG 01A8 CA DEX 01A9 D0 E9 BNE ZON1 01AB 68 PLA 01AC C6 F3 DEC TRIB 01AE F0 05 BEQ SETZ 01B0 30 07 BMI ROUT 01B2 4A LSR A 01B3 90 DB BCC ZON 01B5 A0 00 SETZ LDY #0 01B7 F0 D7 BEQ ZON 01B9 C6 F2 ROUT DEC COUNT 01BB 10 CF BPL TRY 01BD 60 RTS ;frequency/density controls 01BE 02 NPUL .BYTE $02 01BF C3 03 7E TIMG .BYTE $C3, $03, $7E ***** Hex Dump - Hypertape ***** 0100- A9 AD 8D EC 17 20 32 19 A9 27 85 F5 A9 BF 8D 43 0110- 17 A2 64 A9 16 20 61 01 A9 2A 20 88 01 AD F9 17 0120- 20 70 01 AD F5 17 20 6D 01 AD F6 17 20 6D 01 20 0130- EC 17 20 6D 01 20 EA 19 AD ED 17 CD F7 17 AD EE 0140- 17 ED F8 17 90 E9 A9 2F 20 88 01 AD E7 17 20 70 0150- 01 AD E8 17 20 70 01 A2 02 A9 04 20 61 01 4C 5C 0160- 18 86 F1 48 20 88 01 68 C6 F1 D0 F7 60 20 4C 19 0170- 48 4A 4A 4A 4A 20 7D 01 68 20 7D 01 60 29 0F C9 0180- 0A 18 30 02 69 07 69 30 A0 07 84 F2 A0 02 84 F3 0190- BE BE 01 48 2C 47 17 10 FB B9 BF 01 8D 44 17 A5 01A0- F5 49 80 8D 42 17 85 F5 CA D0 E9 68 C6 F3 F0 05 01B0- 30 07 4A 90 DB A0 00 F0 D7 C6 F2 10 CF 60 02 C3 01C0- 03 7E