Apple Assembly Line Volume 1 -- Issue 11 August, 1981 In This Issue... ---------------- Finding Applesoft Line Numbers . . . . . . . . . . . . . . 2 Binary Keyboard Input . . . . . . . . . . . . . . . . . . 3 Apple Machine Language -- A Review . . . . . . . . . . . . 6 Two Ways to Compare a Byte . . . . . . . . . . . . . . . . 9 A Selective Catalog from FID . . . . . . . . . . . . . . . 10 Random Number Generator from Integer BASIC . . . . . . . . 11 What Does This Code Do? . . . . . . . . . . . . . . . . . 15 Correction to "Assembly Source on Text Files" . . . . . . 16 Commented Listing of DOS 3.3 Boot ROM . . . . . . . . . . 17 Renewing Subscriptions ---------------------- The 4-digit number in the upper right corner of your mailing label is the expiration date of your subscription. The first two digits are the year, and the last two digits are the month of the last issue you have paid for. If your label says "8109" or "8110", now is the time to renew to be sure of uninterrupted service. We now have about 500 subscribers, and are shooting for 1000 by the end of the year. (Look for my full page ad in the next NIBBLE.) I am printing 1000 copies of each issue so there will be plenty of back issues for latecomers. Notice that I have a new address. The old one will still work for a while, but you should start using the new one: Bob Sander-Cederlof, S-C Software, P. O. Box 280300, Dallas, TX 75228. Things For Sale --------------- Here is an up-to-date list of some of the things which I have that you might need: Quarterly Disk #1 (source code from Oct 80 - Dec 80)...$15.00 Quarterly Disk #2 (source code from Jan 81 - Mar 81)...$15.00 Quarterly Disk #3 (source code from Apr 81 - Jun 81)...$15.00 S-C ASSEMBLER II Version 4.0...........................$55.00 Beneath Apple DOS (book)...............................$18.00 Apple Machine Language (book)..........................$11.65 Blank Diskettes (Verbatim, with hub rings, no labels, plain white jackets, in cellophane wrapper).................20 disks for $50.00 Zip-Lock Bags (2-mil, 6"x9")...............100 bags for $8.50 If you are interested in getting a regular monthly shipment of 100 or more disks, we can work out an even lower price. If you are in Texas, remember to send 5% sales tax on books, disks, or bags. Finding Applesoft Line Numbers........................Bob Potts --------------------------------------------------------------- Sometimes I have needed to know where in memory a certain Applesoft line is located. Maybe I want to patch in a code which cannot be typed from the keyboard. Or maybe the program has been "compressed and optimized", so that the lines are too long to edit. Or maybe I am just curious. It is simple enough, because the line number is stored in binary at the beginning of each line. I would looke at locations $67,68 to get the address of the first line. Then look at that location to get the address of the next line, and so on. Each line is stored in memory with the first two bytes telling where to find the next line. and the third and fourth bytes giving the line number. Of course, the line number is in binary, and the bytes are backward, and the whole screen is full of hex numbers making it very hard to keep everything straight.... There has to be an easier way! Working with Bob Sander-Cederlof last week, I came up with this simple little program which will print the address of any line in hex. It uses the ampersand (&) statement of Applesoft. You simply BRUN this program, which I call AMPERFIND, and then type an ampersand and the line number. BRUNning sets up the ampersand vector at $3F5-3F7 and returns. Here is the program. Note that it takes more code to set up the ampersand vector than it takes to do the line number search! Lines 1210-1260 could be put anywhere in memory, just so $3F6 and $3F7 are made to point to that place. [Bob Potts is an Assistant Vice President at the Bank of Louisville in Kentucky. this bank has 115 Apple IIs in use doing a variety of banking functions.] 1000 *--------------------------------- 1010 * FIND AN APPLESOFT LINE NUMBER 1020 * AND PRINT ADDRESS IN HEX 1030 *--------------------------------- 1040 .OR $300 1050 .TF AMPERFIND 1060 *--------------------------------- 1070 MON.PRNTAX .EQ $F941 PRINT TWO BYTES IN HEX 1080 AS.LINGET .EQ $DA0C CONVERT LINE NUMBER TO BINARY 1090 AS.FNDLIN .EQ $D61A FIND LINE IN APPLESOFT PROGRAM 1100 *--------------------------------- 1110 * SET UP AMPERSAND VECTOR 1120 *--------------------------------- 1130 LDA #$4C "JMP" OPCODE 1140 STA $3F5 1150 LDA #AMPERFIND 1160 STA $3F6 1170 LDA /AMPERFIND 1180 STA $3F7 1190 RTS 1200 *--------------------------------- 1210 AMPERFIND 1220 JSR AS.LINGET CONVERT LINE NUMBER TO BINARY 1230 JSR AS.FNDLIN FIND THE LINE 1240 LDX $9B 1250 LDA $9C GET THE LINE'S ADDRESS 1260 JMP MON.PRNTAX PRINT THE ADDRESS IN HEX Binary Keyboard Input --------------------- David Holladay, from Madison, Wisconsin, wrote a recent article for the Adam & Eve Apple II Users Group about a technique he uses for turning the Apple keyboard into a Braille input device. He chose 6 keys which can be "simultaneously" depressed to give a composite code. The keys form a 2-by-3 rectangle, like the dots of Braille characters. Because the Apple keyboard has N-key rollover, simultaneous depression of several keys results in each keycode being sent to the program one at a time. The order that the codes are produced appears random to the program. Some quirks in the way the Apple keyboard is wired up prevent the N-key rollover from working with every combination of keys. Some of them OR together to create a ghost code, different from the actual depressed keys. Apple has used many different keyboards, so the keys which can be used for David's program vary considerably from one Apple to another. After playing around with his program for a while, I got interested in making a Binary Input Keyboard, rather than a Braille one. My keyboard, which is almost 4 years old (Apple serial # 219!), allows me to press any combination of the keys J, K, L, 1, 2, 3, and 4. I set up these keys with binary weights of hex 40, 20, 10, 08, 04, 02, and 01 respectively. When you type a combination of these seven keys all at once, the time interval between keys is much shorter than the normal spacing between keystrokes. The program waits for one keyboard strobe, and then initiates a timeout loop. All keycodes received within the timeout window will be considered to have been struck "simultaneously". Each keycode is compared with the list of seven keys (JKL1234), and the appropriate binary weight ORed into the character. If a keycode is received which is not in the legal character list, the bell rings. I made a test loop which calls the input routine, and displays the hex code on the screen. The choice of keys (JKL1234) works fine on my Apple, but it may not work on yours. Experiment with various choices until you find seven keys which will work together on your keyboard. Then modify line 1420 with your list of keys, and it will be ready to go. Possible applications? Maybe fast input of hexadecimal machine language programs. You would have to add one more key so that all eight bits could be specified. And you would have to train your mind and fingers to instantaneously translate from hex to binary finger-patterns. Or, maybe some sort of a game. The basic idea of reading simultaneous keystrokes could effectively create new keys. Or, maybe the basic idea of simultaneous keystrokes could be used for entering secret passwords. 1000 *--------------------------------- 1010 * BINARY KEYBOARD 1020 *--------------------------------- 1030 MON.CH .EQ $24 1040 MON.CV .EQ $25 1050 KEYBOARD .EQ $C000 1060 STROBE .EQ $C010 1070 MON.VTAB .EQ $FC24 1080 MON.HOME .EQ $FC58 1090 MON.BELL .EQ $FBE2 1100 MON.PRBYTE .EQ $FDDA 1110 *--------------------------------- 1120 GETCHR LDA #0 1130 .1 STA CHARCODE 1140 LDA #-16 1150 STA CNTR 1160 STA CNTR+1 1170 .2 LDA KEYBOARD 1180 BMI .4 SOMETHING TYPED 1190 INC CNTR 1200 BNE .2 1210 INC CNTR+1 1220 BNE .2 1230 LDA CHARCODE GET COMPOSITE CODE 1240 BEQ GETCHR NO KEYS HIT YET 1250 .3 RTS 1260 *--------------------------------- 1270 .4 STA STROBE CLEAR KEYBOARD STROBE 1280 AND #$7F 1290 CMP #$20 HANDLE BLANK SEPARATELY 1300 BEQ .3 1310 LDY #6 SEARCH LIST OF LEGAL KEYS 1320 .5 CMP LEGAL.KEYS,Y 1330 BEQ .6 1340 DEY 1350 BPL .5 1360 JSR MON.BELL 1370 JMP GETCHR 1380 .6 LDA KEY.BITS,Y 1390 ORA CHARCODE 1400 BNE .1 ...ALWAYS 1410 *--------------------------------- 1420 LEGAL.KEYS .AS /JKL1234/ 1430 KEY.BITS .HS 40201008040201 1440 *--------------------------------- 1450 CHARCODE .BS 1 1460 CNTR .BS 2 1470 *--------------------------------- 1480 * TEST BINARY KEYBOARD 1490 *--------------------------------- 1500 TEST JSR MON.HOME 1510 .1 JSR GETCHR 1520 STA $403 LINE 1, COLUMN 4 OF SCREEN 1530 LDA #0 1540 STA MON.CH 1550 STA MON.CV 1560 JSR MON.VTAB 1570 LDA $403 1580 JSR MON.PRBYTE 1590 JMP .1 Apple Machine Language -- A Review ---------------------------------- Many of you have asked me, "What book will help me, an absolute beginner, learn 6502 machine language? I don't know what these other books are talking about!" If these are your words, then the book "Apple Machine Language", by Don and Kurt Inman, is for you. It is published by Reston Publishing Company, in both hardback ($17.95) and paperback ($12.95). The book has 296 pages, is set in clear, easy-to-read type, and has lots of good diagrams and illustrations. The authors assume that you are at least familiar with Applesoft Basic. Chapter 1 gives a brief review of Applesoft, with special emphasis on the PEEK, POKE, and CALL statements. (These are the statements you will be using to communicate between Basic and machine language programs.) The authors also assume that you have your own Apple, and that you will not just READ the book. They expect you to follow along every example with your own Apple, so you can EXPERIENCE the material. You will not only learn a lot faster, but it will stick with you and you will UNDERSTAND what is going on. Chapter 2 takes you across the bridge from Basic to machine language, very gently. You develop, with the authors, a little Applesoft program which helps you enter and test machine language programs. Chapter 3 finally introduces the ideas of binary numbers, hexadecimal, the A-register in the 6502, and a few instruction codes. You will learn how to load a value into the A-register, modify that value, and store the result back into memory. There are exercises at the end of each chapter which review the material covered. Don't let that worry you, though...they also printed the answers! Chapter 4 starts to get interesting and useful. You learn how to use machine language to put some simple color graphics on the Apple screen. You can plot individual points, draw rectangles, and color them in. All the while, you are learning more machine instructions, more registers, more about memory addressing, and so forth. Chapter 5 introduces you to writing text on the screen. You learn how to call some of the monitor subroutines for text output, how to print characters at particular screen locations, and how to write messages of your choice. Some new instructions are covered, and you learn some new address modes. In particular, you learn all about relative branching. Chapter 6 is one of my favorites. I have always enjoyed twiddling Apple's little built-in speaker, and this chapter shows you how. You build and play with a tone generator program, even to the point of tuning it up to make a simulated piano keyboard. Chapter 7 takes you deeper into sound and graphics, helping you code a routine to display the notes as you play them from the keyboard. By the time you finish this chapter you will understand how to use 28 of the 6502's 56 instructions, and 8 of its 13 addressing modes. You will also have used 9 of the subroutines found inside the Apple Monitor ROM. Chapter 8 takes you inside Apple's Monitor...just a little. Until now, you have been using the Applesoft program developed in chapter 2 to enter and test all your machine language programs. In chapter 8 you learn how to do it from the monitor. You will also learn how to do addition and subtraction. Chapter 9 show you how to add numbers too big to fit in one byte. Since one byte will only hold numbers between 0 and 255, or between -128 and +127, you can see that most numbers ARE too big to fit in one byte. You will also learn all about the way negative numbers are handled in the 6502. Chapter 10 delves deeper into the Apple Monitor, and explores 6502 decimal mode arithmetic. Chapter 11 is only for those fortunate readers who have Integer BASIC in their Apples. It doesn't matter whether Integer BASIC is on the Apple Monitor board, on a firmware card in ROM, or in a 16K RAM card...just so you have it. Why? Because there is another program in there you might not even be aware of: the Apple Mini-Assembler. If you are lucky enough to have it, chapter 11 will tell you how to use it. If not, skipover this chapter and use your S-C ASSEMBLER II instead! On second thought, don't skip chapter 11 entirely. It is here that indirect addressing is covered, and you need to know this material. Chapter 12, "Putting It All Together", puts it all together. The programming experience you work through is a multiplication subroutine. There are four appendices which summarize the information about the Apple hardware found throughout the book. Several of the charts in Appendix-A list page number references. (Early editions of the book had blank columns where the page numbers were supposed to be, but that has been corrected.) And finally, there is a regular alphabetic index. By the time you finish this book, you have a solid foundation for learning to use an assembler like the S-C ASSEMBLER II. I would like to think that my assembler is easy enough to learn that books like this one would not be needed, but there are a lot of concepts that are completely foreign to new computer owners. I want to do all I can to help every one of you become proficient in assembly language, so I am making "Apple Machine Language" available to you at a discount. You can buy the $12.95 paperback edition from me for $11.65 (plus 58 cents tax if you are in Texas). Include a dollar for shipping, so I don't go broke. Two Ways to Compare a Byte.........................Lee Meador ------------------------------------------------------------- I have noticed two ways to compare a byte used inside DOS and other Apple software. In the cases I am thinking of, the following code required the Y-register to be zero. The first way I have seen is straightforward: LDA ... BYTE TO BE TESTED CMP #$19 VALUE WE WANT TO TEST FOR BNE .1 ALSO AFFECTS CARRY STATUS LDY #0 IF =, CARRY SET ... The other way is a little trickier, but it saves one byte: LDA ... BYTE TO BE TESTED EOR #$19 VALUE WE WANT TO TEST FOR BNE .1 DOESN'T AFFECT CARRY STATUS TAY A AND Y BOTH ZERO ... This may help you understand some of those disassemblies you are making, or help you save a byte here and there. A Selective Catalog from FID.........................Lee Meador --------------------------------------------------------------- If you have DOS 3.3, you have no doubt enjoyed using the FID program to copy files from one disk to another. The wildcard feature in filenames is especially nice, because it lets you set up a semi-automatic copy of a whole set of files, or even the whole disk. Sometimes I am reluctant to let the wildcard name go through without prompting, because there might be a file or two I don't want copied which matches the specified name. However, there are so many files involved that I really don't want to sit there and type "Y" for every one of them. What we need is a "selective catalog" command -- a FID command to list all files names which match the wildcarded-name. Here are some easy patches which you can apply to FID which will convert the VERIFY command to just what we want. ]BLOAD FID load FID ]CALL -151 get to Apple's monitor *DBE:60 return before verifying *C10:EA EA EA no double spacing *3D0G return to BASIC ]BSAVE FID/CATALOG,A$803,L$124E save the new version Now if you BRUN FID/CATALOG you will see the normal FID menu. Select option 8 (VERIFY), specify a slot and drive, and type a file name (preferably with the "=" wildcard in it). Specify NO prompting. When you "PRESS ANY OTHER KEY TO BEGIN" you will see a list of all files whose names match the filename you typed. Someone else will have to figure out how to get the file type and size to print. Random Number Generator from Integer BASIC ------------------------------------------ When you are writing games or other simulation exercises, you frequently need a source of random numbers. In Basic it's easy, but how about assembly language? The WozPak from Call A.P.P.L.E. has directions for calling the RND(X) function in the Integer BASIC ROMs. Remember that this function returns a random integer between 0 and X-1 for an argument X. Linda Egan, from Maywood, California, wrote that she had trouble making the WozPak method work. I don't know what that method was, but I looked up the code in the ROM and came up with some working code. 1000 *--------------------------------- 1010 * RANDOM FUNCTION 1020 * --------------- 1030 * CALLS SUBROUTINE IN INTEGER BASIC ROM TO GET 1040 * A RANDOM NUMBER BETWEEN 0 ANT X-1 1050 * 1060 * CALL: VALUE X IN Y- AND A-REGISTERS 1070 * JSR RANDOM 1080 * RETURN: RANDOM NUMBER IN Y- AND A-REGISTERS 1090 * LO-BYTE IN Y, HI-BYTE IN A 1100 *--------------------------------- 1110 IB.ARG .EQ $CE,CF 1120 IB.LOSTACK .EQ $50 THRU $6F 1130 IB.HISTACK .EQ $A0 THRU $BF 1140 *--------------------------------- 1150 IB.RANDOM .EQ $EF51 1160 MON.PRBYTE .EQ $FDDA 1170 MON.COUT .EQ $FDED 1180 *--------------------------------- 1190 RANDOM LDX #$20 I/B NOUN-STACK POINTER 1200 STA IB.ARG+1 1210 STY IB.ARG 1220 LDY #0 FLAG VALUE ON STACK 1230 JSR IB.RANDOM 1240 LDA IB.HISTACK,X 1250 LDY IB.LOSTACK,X 1260 RTS 1270 *--------------------------------- 1280 TEST.RANDOM 1290 LDA #160 1300 STA COUNT 1310 .1 LDY #1000 1320 LDA /1000 1330 JSR RANDOM RND(1000) 1340 JSR MON.PRBYTE 1350 TYA 1360 JSR MON.PRBYTE 1370 LDA #$A0 PRINT BLANK 1380 JSR MON.COUT 1390 DEC COUNT 1400 BNE .1 1410 RTS 1420 COUNT .BS 1 Lines 1190-1260 are all you need. They set up a call to the ROM code, and pick up the returned value. Line 1190 sets the X-register to $20. The ROM code uses X for a stack index, and $20 means an empty stack. This is not the hardware stack ($100-1FF), but a software-implemented stack. The stack is in three parts. The part I call IB.LOSTACK runs from $50 thru $6F. IB.HISTACK runs from $A0 thru $BF. A third part runs from $78 thru $97. The ROM code pushes our argument on these stacks like this: the low byte goes on LOSTACK, the high byte on HISTACK, and a zero (from the Y-register) on the FLAGSTACK. (If the value pushed on FLAGSTACK was not zero, it would be used as the high-byte of an address along with the low-byte from LOSTACK to indirectly address the data value.) Lines 1200 and 1210 store our argument where the ROM code expects it to be, in $CE and $CF. Lines 1240 and 1250 retrieve the resulting random number from the stack. Lines 1280 through 1420 are a test loop to demonstrate the random function. Twenty lines of eight random numbers each are printed on the screen in hexadecimal. I used an argument of 1000, so all the numbers are between 0 and 999. What if you don't have the Integer BASIC ROMs in your Apple? Since the code is not very long, you could make your own copy of Woz's routines. I did that, and came up with the following program. I used the same test loop, but this time it is in lines 1760 thru 1900. 1000 *--------------------------------- 1010 * STAND-ALONE RANDOM FUNCTION 1020 * --------------------------- 1030 * 1040 * GET A RANDOM NUMBER BETWEEN 0 AND X-1 1050 * 1060 * CALL: VALUE X IN Y- AND A-REGISTERS 1070 * JSR RANDOM 1080 * RETURN: RANDOM NUMBER IN Y- AND A-REGISTERS 1090 * LO-BYTE IN Y, HI-BYTE IN A 1100 *--------------------------------- 1110 MON.RNDL .EQ $4E 1120 MON.RNDH .EQ $4F 1130 MON.PRBYTE .EQ $FDDA 1140 MON.COUT .EQ $FDED 1150 *--------------------------------- 1160 RANDOM STY LIMIT SAVE LIMIT VALUE 1170 STA LIMIT+1 1180 LDA MON.RNDH GET SEED HI-BYTE 1190 BNE .1 BE SURE SEED BTWN 1 AND 7FFF 1200 CMP MON.RNDL SET CARRY IF BOTH BYTES ZERO 1210 ADC #0 CHANGE 0000 TO 0100 1220 .1 AND #$7F MAKE SURE NOT LARGER THAN 7FFF 1230 STA MON.RNDH 1240 STA VALUE+1 1250 LDA MON.RNDL 1260 STA VALUE 1270 LDA #0 1280 STA VALUE+2 1290 STA VALUE+3 1300 *--------------------------------- 1310 LDY #17 LOOP TO MAKE NEXT RANDOM VALUE 1320 .2 LDA MON.RNDH (WOZNIAK'S ALGORITHM) 1330 ASL 1340 CLC 1350 ADC #$40 1360 ASL 1370 ROL MON.RNDL 1380 ROL MON.RNDH 1390 DEY 1400 BNE .2 1410 *--------------------------------- 1420 LDA LIMIT 1430 ORA LIMIT+1 1440 BEQ .5 RETURN ZERO 1450 *--------------------------------- 1460 * DIVIDE RANDOM VALUE (1-7FFF) BY LIMIT 1470 * AND USE REMAINDER (0<=REMAINDER32767 ERR" with a zero argument. Lines 1490-1650 are a division program, to divide the random VALUE by the LIMIT. After it is finished, the quotient is in VALUE and VALUE+1, and the remainder is in VALUE+2 and VALUE+3. We don't need the quotient; the remainder is the random value we want. Lines 1690-1710 pick up the result in registers A and Y, and return to the calling program. What Does This Code Do?..........................John Broderick --------------------------------------------------------------- What does it do? Why would you want to use it? Those who send in correct answers will get their names published here in a few months with the solution. SUBROUTINE: BRK PLA PLA PLA RTS OK, I'll give you a little hint. One of the five instructions is not used by the 6502 processor. Can you tell which one? As far as I know, this routine has never before been published; however, I use it in almost every program I write. It's a jewel of a routine, worth many times its weight in gold! Send your answers to John Broderick, 8635 Shagrock, Dallas, TX 75238. If you have any similar neat code segments, send them with explanation. I'll try to make this a regular column in the AAL. Correction to "Assembly Source on Text Files" --------------------------------------------- Volume 1, Issue 2 of Apple Assembly Line contained a program for writing assembly source programs for the S-C Assembler II Version 4.0 on DOS text files. Peter Bartlett of Chicago was trying to use it with a Corvus Hard Disk, and found a problem with the program. The Corvus system will not accept a CLOSE command unless there is a file name on it (unlike regular DOS). One solution is to delete the two calls to CLOSE.FILE at lines 1410 and 1570. While talking with Peter I discovered a bug in my program, in the subroutine named ISSUE.DOS.COMMAND. It is supposed to allow slot and drive parameters on the file name. This was described in the write-up on page 11. Two errors made it not work. First, line 1910 says: 1910 CMP #', COMMA? but the character in the A-register has the high bit set to one. Change line 1910 to: 1910 CMP #$AC COMMA? Second, line 1940 says: 1940 STA DOS.BUFFER,Y Change it to: 1940 STA DOS.BUFFER-1,Y The line numbers above correspond to the printed listing in the AAL article. They may not be exactly the same as the source code on Quarterly Disk #1. If you have Quarterly Disk #1 with a serial number of 45 or higher, your copy is already fixed. About Advertising ----------------- Do you have a new product you want to test market, which would appeal to the Apple Assembly Line readers? You ought to try an ad in these pages. The current price is $20 for a full page, $10 for a half page. Send it to me just as you want it printed (I can do the reduction to make it fit on the page). Commented Listing of DOS 3.3 Boot ROM ------------------------------------- The P5A ROM on your Apple Disk II Controller has a 256-byte program in it which reads track 0 sector 0 into memory and starts executing it. The data in track 0 sector 0 is read into memory from $0800-08FF. Location $0800 contains a value indicating how many sectors to boot in. This is usually zero, meaning to read only sector zero. However, it could be as high as $0F, meaning to read all 16 sectors of track 0 into memory from $0800-17FF. (The BASICS diskette uses this feature.) Once the selected number of sectors has been read, the boot ROM jumps to $0801 to start execution. At this point (in a normal DOS boot) the rest of DOS is loaded. My listing starts at $C600, which is where it will be if your controller is in slot 6. The code is all independent of position, so that it can be plugged into any slot. In fact, you can move the code into RAM if you like, just so the second digit of the address is the same as the controller card slot number. I do this some times when I am trying to crack locked disks. I go to the monitor, type 8600 LOW BYTE OF PNTR) 2040 STA SECTOR 0 2050 STA TRACK 0 2060 LDA #8 BUFFER AT $0800 2070 STA BUFFER.PNTR+1 ($08 --> HI-BYTE OF PNTR) 2080 *--------------------------------- 2090 READ.SECTOR 2100 .1 CLC FLAG CLEAR, LOOK FOR $D5 AA 96 2110 .2 PHP SAVE FLAG ON STACK 2120 .3 LDA Q6L,X READ DISK 2130 BPL .3 2140 .4 EOR #$D5 2150 BNE .3 NO 2160 .5 LDA Q6L,X READ DISK 2170 BPL .5 2180 CMP #$AA 2190 BNE .4 2200 NOP 2210 .6 LDA Q6L,X READ DISK 2220 BPL .6 2230 CMP #$96 2240 BEQ .7 FOUND ADDRESS MARK: $D5 AA 96 2250 PLP RETRIEVE FLAG 2260 BCC .1 LOOKING FOR ADDRESS HEADER 2270 EOR #$AD LOOKING FOR DATA HEADER 2280 BEQ FILL.BUFFER 2290 BNE .1 START ALL OVER 2300 *--------------------------------- 2310 .7 LDY #3 READ VOLUME, TRACK, SECTOR 2320 .8 STA $40 2330 .9 LDA Q6L,X READ DISK 2340 BPL .9 2350 ROL SAVE UPPER SLICE 2360 STA $3C 2370 .10 LDA Q6L,X READ DISK 2380 BPL .10 2390 AND $3C MERGE SLICES 2400 DEY 3RD BYTE YET? 2410 BNE .8 NO, GET ANOTHER 2420 PLP THROW AWAY FLAG 2430 CMP SECTOR CORRECT SECTOR? 2440 BNE .1 NO 2450 LDA $40 CORRECT TRACK? 2460 CMP TRACK 2470 BNE .1 NO 2480 BCS .2 YES, SET FLAG FOR DATA HEADER 2490 * AND BRANCH BACK ALWAYS 2500 *--------------------------------- 2510 * A=0 ON ENTRY 2520 *--------------------------------- 2530 FILL.BUFFER 2540 LDY #86 READ 86 BYTES 2550 .1 STY $3C 2560 .2 LDY Q6L,X READ BYTE 2570 BPL .2 2580 EOR POST.NYBBLE.CODES,Y DECODE BYTE 2590 LDY $3C 2600 DEY 2610 STA LITTLE.BUFFER,Y 2620 BNE .1 2630 *--------------------------------- 2640 .3 STY $3C Y=0 2650 .4 LDY Q6L,X READ BYTE 2660 BPL .4 2670 EOR POST.NYBBLE.CODES,Y DECODE BYTE 2680 LDY $3C 2690 STA (BUFFER.PNTR),Y 2700 INY 2710 BNE .3 2720 .5 LDY Q6L,X READ CHECKSUM BYTE 2730 BPL .5 2740 EOR POST.NYBBLE.CODES,Y 2750 .6 BNE READ.SECTOR BAD CHECKSUM, START OVER 2760 *--------------------------------- 2770 LDY #0 2780 .7 LDX #86 PATCH THE 6+2 BACK TOGETHER 2790 .8 DEX 2800 BMI .7 FINISHED A TRIP 2810 LDA (BUFFER.PNTR),Y 2820 LSR LITTLE.BUFFER,X 2830 ROL 2840 LSR LITTLE.BUFFER,X 2850 ROL 2860 STA (BUFFER.PNTR),Y 2870 INY 2880 BNE .8 2890 *--------------------------------- 2900 INC BUFFER.PNTR+1 POINT AT NEXT PAGE 2910 INC SECTOR POINT AT NEXT SECOTR 2920 LDA SECTOR 2930 CMP $0800 SEE IF HAVE READ ENUF SECTORS 2940 LDX SLOT16 2950 BCC .6 NOT ENUF SECTORS YET 2960 JMP $0801 GO TO REST OF BOOT 2970 *--------------------------------- 2980 .HS 0000000000 UNUSED BYTES IN ROM