Volume 6 -- Issue 1 | October 1985

In This Issue...

- ProDOS Snooper
- Different Patch for 65C02 & Old Apples
- DOS 3.3 RWTS Snooper
- Feedback about the Latest Sieve
- Paint Yourself into the Corner
- Index to Apple Assembly Line, Volume 5
- Multiple Column Dis-Assembly
- Apple Manuals from Addison-Wesley
- Now That You Know Apple Assembly Language

Book, Books, Books

Inside this issue you will find a review of Jules Gilder's new book on intermediate-level Apple assembly language programming, and the details on those long-awaited Addison-Wesley editions of Apple's Technical Manuals. We're now offering these items for sale, and the details are in our ad.

The latest word from Prentice-Hall is that David Eyes' "Programming the 65816" will be shipped on October 29, so we may actually have copies by the time you read this. Bob will have a full review next month, and we are beginning to get orders already. The list price is expected to be $22.95. If that holds, our price will be $21.00 + postage.

A Rumor Regarding the Next Apple II

We have heard from two sources now a rumor that Apple does not plan to use the 65816 in its next Apple II. Nor the 65802, nor the 65C02. Instead, we heard, they will use a custom version of the 68000 family with 65C02 emulation capability. I think that I hope that the rumor is groundless, but I'll keep my ear to the ground anyway.

ProDOS Snooper | Bob Sander-Cederlof

This past week I have been working on a project which involved creating a new device driver for a disk-like device. In the process of debugging my driver, I had to write a "snooper" program.

By "snooper", I mean a program which will make a list of all calls to the driver, recording the origin of the call and the parameters of the call.

ProDOS keeps a table of the addresses of the device drivers assigned to each slot and drive between $BF10 and $BF2F. There are two bytes for each slot and drive. $BF10-1F is for drive 1, and $BF20-2F is for drive 2. For example, the address of the device driver for slot 6 drive 1 is at $BF1C,1D. (Normally this address is $D000.)

I have a Sider drive in slot 7. The device driver address for the Sider is $C753, and is kept at $BF1E,1F and $BF2E,2F.

By patching the device driver address to point to my own code, I can get control whenever ProDOS tries to read or write or whatever. If I save and restore all the registers, and jump to the REAL device driver after I am finished, ProDOS will never be the wiser. But I will!

While my program has control, I can capture all the information I am interested in. Unfortunately I cannot print it out at this time, because if I try to ProDOS will get stuck in a loop. Instead I will save the data in a buffer so I can look at it later.

The program which follows has three distinct parts. Lines 1140-1290 are an installation and removal tool. If the program has just been BLOADed or LOADed and ASMed, running INSTALL.SNOOPER will (you guessed it!) install the snooper. The actual device driver address for the slot (which you specified in line 1060 before assembling the program) will be saved in my two-byte variable DRIVER. The previous contents of DRIVER, which is the address of my snoop routine, will be copied into ProDOS's table. The value of DRIVES, which you specified before assembling the program at line 1070, will determine whether SNOOPER is connected to drive 2 or not. It will always be connected to drive 1.

If SNOOPER has already been installed, running INSTALL.SNOOPER will reverse the installation process, returning ProDOS to its original state. INSTALL.SNOOPER also resets the buffer I use to keep the captured information. To make it easy to run INSTALL.SNOOPER, I put a JMP to it at $300. After assembly you can type "$300G" to install the snooper, and type the same again to dis-install it.

The JMP at $303 (line 1120) goes to the display program. After SNOOPER has been installed, all disk accesses on the installed slot will cause information to be accumulated in BUFFER. Typing "$303G" will cause the contents of BUFFER to be displayed in an easy-to-read format.

I set up SNOOPER to capture eight bytes of information each time it is activated. You might decide to save more or less. I save the return address from the stack, to get some idea of which routine inside ProDOS is trying to access the disk. I also save the six bytes at $42-47, which are the calling parameters for the device driver. Page 6-8 of Beneath Apple ProDOS describes these parameters; you can also find out about them in Apple's ProDOS Technical Reference Manual and in Gary Little's "Apple ProDOS--Advanced Features".

$42 contains the command code: 00=status, 01=read, 02=write, and 03=format. $43 contains the unit number, in the format DSSS0000 (where SSS=slot and D=0 for drive 1, D=1 for drive 2). $44-45 contain the address of the memory buffer, lo-byte first; the buffer is 512 bytes long. $46-47 contain the block number to be read or written.

My DISPLAY program displays each group of eight bytes on a separate line, in the following format:

         hhll:cc.uu.buff.blok

where hhll is the return address from the stack, hi-byte first; cc is the command code; uu is the unit number; buff is the buffer address, hi-byte first; blok is the block number, hi-byte first.

If you get into figuring out more of what ProDOS is doing, you might want to save more information from the stack. You can look behind the immediate return address to get more return addresses and other data which have been saved on the stack before calling the device driver.

A word of explanation about lines 1040, 1360, 1370, 1490, and 1500. Line 1040 tells the S-C Macro Assembler that it is OK to assemble opcodes legal in the 65C02. The PHX, PHY, PLX and PLY opcodes are in the 65C02, 65802, and 65816; however, they are not in the 6502. If you have only the 6502 in your Apple, you will need to substitute the longer code shown in the comments. Leave out line 1040, and use the following:

           1360    TYA
           1365    PHA
           1370    TXA
           1375    PHA
           .
           .
           .
           1490    PLA
           1495    TAX
           1500    PLA
           1505    TAY

In the process of "snooping" I was able to debug my new device drivers for the project I was developing. I also discovered what appear to be some gross in-efficiencies in ProDOS. In the course of even simple CATALOGs, LOADs, and SAVEs the same blocks are read into the same buffers over and over, at times when it would appear to be totally unnecessary. If there was some mechanism inside MLI to keep track of the fact that a complete un-spoiled copy of a particular block was already in RAM, it could save a lot of time. On the other hand, it could be that the current approach is safer. I think it is a potentially fruitful area for further investigation. Any takers?

      1010 *SAVE PRODOS.SNOOPER
      1020 *--------------------------------
      1030        .OR $300
      1040        .OP 65C02    (If you have one)
      1050 *--------------------------------
      1060 SLOT   .EQ 6
      1070 DRIVES .EQ 2
      1080 *--------------------------------
      1090 BUFFER .EQ $800
      1100 *--------------------------------
      1110 A300   JMP INSTALL.SNOOPER
      1120 A303   JMP DISPLAY
      1130 *--------------------------------
      1140 INSTALL.SNOOPER
      1150        LDX #1
      1160 .1     LDA 2*SLOT+$BF10,X
      1170        PHA          SAVE CURRENT DRIVER ADDRESS
      1180        LDA DRIVER,X INSTALL NEW DRIVER ADDRESS
      1190        STA 2*SLOT+$BF10,X
      1200   .DO DRIVES=2
      1210        STA 2*SLOT+$BF20,X
      1220   .FIN
      1230        PLA          REMEMBER OLD DRIVER
      1240        STA DRIVER,X
      1250        LDA BUFFER.ADDR,X
      1260        STA A+1,X
      1270        DEX
      1280        BPL .1       NOW THE OTHER BYTE
      1290        RTS
      1300 *--------------------------------
      1310 DRIVER      .DA SNOOPER
      1320 BUFFER.ADDR .DA BUFFER
      1330 *--------------------------------
      1340 SNOOPER
      1350        PHA
      1360        PHY      (If no 65C02 use TYA, PHA)
      1370        PHX      (If no 65C02 use TXA, PHA)
      1380        TSX
      1390        LDA $104,X   LO-BYTE OF RETURN ADDR
      1400        JSR STORE.BYTE
      1410        LDA $105,X   HI-BYTE OF RETURN ADDR
      1420        JSR STORE.BYTE
      1430        LDX #0       $42...47
      1440 .1     LDA $42,X    WHICH ARE THE PARAMETERS
      1450        JSR STORE.BYTE     FOR THE CALL
      1460        INX
      1470        CPX #6
      1480        BCC .1
      1490        PLX      (If no 65C02 use PLA, TAX)
      1500        PLY      (If no 65C02 use PLA, TAY)
      1510        PLA
      1520        JMP (DRIVER) CONTINUE IN DRIVER
      1530 *--------------------------------
      1540 STORE.BYTE
      1550 A      STA BUFFER   THIS ADDRESS IS MODIFIED
      1560        INC A+1      BUMP PNTR TO NEXT ADDRESS
      1570        BNE .1
      1580        INC A+2
      1590 .1     RTS
      1600 *--------------------------------
      1610 COUT   .EQ $FDED
      1620 CROUT  .EQ $FD8E
      1630 PRBYTE .EQ $FDDA
      1640 PNTR   .EQ $00,01
      1650 *--------------------------------
      1660 DISPLAY
      1670        LDA #BUFFER  SET UP PNTR INTO BUFFER
      1680        STA PNTR
      1690        LDA /BUFFER
      1700        STA PNTR+1
      1710 *---CHECK IF FINISHED------------
      1720 .1     LDA PNTR
      1730        CMP A+1
      1740        LDA PNTR+1
      1750        SBC A+2
      1760        BCC .2
      1770        RTS
      1780 *---DISPLAY NEXT 8 BYTES---------
      1790 .2     LDY #1
      1800        JSR WORD     DISPLAY RETURN ADDRESS
      1810        LDA #":"     "XXXX:"
      1820        JSR COUT
      1830        JSR BYTE     DISPLAY ($42)=OPCODE
      1840        JSR BYTE     DISPLAY ($43)=UNIT NUMBER
      1850        INY
      1860        JSR WORD     DISPLAY ($44,45)=BUFFER ADDR
      1870        JSR DOT
      1880        JSR WORD     DISPLAY ($46,47)=BLOCK NUMBER
      1890        JSR CROUT    CARRIAGE RETURN
      1900        LDA PNTR     ADVANCE PNTR TO NEXT
      1910        CLC               GROUP OF 8 BYTES
      1920        ADC #8
      1930        STA PNTR
      1940        BCC .1
      1950        INC PNTR+1
      1960        BNE .1       ...ALWAYS
      1970 *--------------------------------
      1980 WORD   LDA (PNTR),Y      DISPLAY HI-BYTE
      1990        JSR PRBYTE
      2000        DEY               DISPLAY LO-BYTE
      2010        LDA (PNTR),Y
      2020        INY
      2030        INY               ADVANCE INDEX
      2040        JMP PRBYTE
      2060 *--------------------------------
      2070 BYTE   LDA (PNTR),Y      DISPLAY BYTE
      2080        JSR PRBYTE
      2090 DOT    LDA #"."          PRINT "."
      2100        INY               ADVANCE INDEX
      2110        JMP COUT
      2120 *--------------------------------

A Different Patch for 65C02 & Old Apples | William O'Ryan Jr.

Since my earlier letter (Jun 84) on the 65C02 and the Apple II+ I was interested and gratified to read Andrew Jackson's (Dec 84) and Jim Sather's (Mar 85) letters on the same subject. However, two things began to worry me. First, the smallness of the time gain in the F257 chips (around 7 nanoseconds, I understand). That did not seem enough to be very reliable. Second, a friend in town has an Apple whose speed was not sufficiently improved to allow the 65C02 to work (although there was some noticeable improvement).

After reading the first few chapters of Jim Sather's book, "Understanding the Apple II", I was able to come up with a new solution. As I figure it, this new solution yields an improvement of around 70 nanoseconds, more than enough. Simply put, just replace the -RAS line inputs to the 74LS174 chips at B5 and B8 with AX. AX rises 70 nsec earlier than -RAS, enabling those chips to latch RAM output 70 nsec earlier. It is a simple patch and may be done either with or without altering the motherboard.

I tried it first without altering my motherboard, on a Rev 44-1 Apple using 200 nsec 16K RAM chips. I was surprised to see it work, as I had expected that 200 nsec RAM chips would be too slow for the patch. (I haven't tried it yet with 250 nsec RAM chips.) Actually, this particular Apple did not need any speed-up -- the 65C02 was already working in it.

To do this patch: remove the chips at B5 and B8; seat an extra socket under each of them; pin 9 on these sockets should be bent out so they do not go into the motherboard sockets; remove the chip at C2 and put an extra socket under it; connect a wire from pin 14 of the C2 socket to the bent out pins 9 of B5 and B8. Pin 14 of the 74S195 at C2 is a source of the AX signal; pin 9 of B5 and B8 was previously connected to -RAS.

I have another Apple (Rev 4) which has 24 150 nsec 64K RAM chips (using the Cramapple mod). This Apple already had F257's in it with a 65C02. I put the old LS257's back in, and sure enough the 65C02 began to stumble. Then I removed the motherboard and on the underside cut the trace to -RAS and soldered in a jumper wire to pin 14 of C2. It worked perfectly!

Naturally those who try any of these patches do so at their own risk.

I must thank Jim Sather for his book; it was only by studying the timing diagrams in that book and staring at the circuit diagram published by Apple that I was able to do this. I hope some of the hardware types will be able to tell me if I have built a time bomb. I am also very interested to hear whether the problem with the 65802 is the same.

DOS 3.3 RWTS Snooper | Bob Sander-Cederlof

Of course if I want to look around in ProDOS the same curiosity certainly applies to DOS 3.3. The fact of the matter is, I started snooping in DOS first; nevertheless, the ProDOS article took precedence in these pages.

There are several nice places to patch a snooper into DOS 3.3. One is right at the beginning of RWTS, $BD00. This position is usually taken by hard disks, however. For example, Sider and Corvus use $BD00. I could skip down below $BD00, but Sider for one expects several bytes after $BD00 to be normal DOS code. Looking backward, $BD00 is normally called only from a subroutine which starts at $B7B5. This subroutine, in turn, is normally only called from $B090. Your own programs may call RWTS differently, but DOS itself almost always goes through $B090. (The exceptions are the reading and writing of the DOS image during boot or INITialization.)

Therefore...I patched my SNOOPER program in at $B090. The INSTALL.SNOOPER code in lines 1060-1160 is very similar to that in the ProDOS snooper. It swaps the address currently in my variable DRIVER with the address at $B091,2. Typing "$800G" will install SNOOPER, and typing it again will dis-install SNOOPER.

The DOS snooper prints out each line of information as it goes along, without storing the data. Each line contains the two most recent return address from the stack, so you can trace who is calling RWTS. I also print out the RWTS command, the track and sector, and the buffer address.

Here is an example of the printout, in this case during a SAVE operation:

         :LOAD S.RWTS.SNOOPER
         :ASM                     Assembler SNOOPER

         0000 ERRORS IN ASSEMBLY
         :$800G                   install SNOOPER
         :SAVE S.RWTS.SNOOPER     sample DOS command
         AB24.AD45.01.11.00.B3BB  read VTOC
         AB45.B1E6.01.11.0F.B4BB  read Catalog sector
         A6AA.AB24.01.1F.0F.9700  T/S list
         C3E9.ACDD.01.1F.0E.9600  read 1st data sector
         ACDD.B0C8.02.1F.0E.9600  write 1st data sector
         D349.ACDD.01.1F.0D.9600  read 2nd data sector
         ACDD.B0C8.02.1F.0D.9600  write 2nd data sector
         D328.ACDD.01.1F.0C.9600  read 3rd data sector
         ACDD.B0C8.02.1F.0C.9600  write 3rd data sector
         D352.ACDD.01.1F.0B.9600  read 4th data sector
         ACDD.B0C8.02.1F.0B.9600  write 4th data sector
         A2F8.A6AA.01.11.00.B3BB  read VTOC
         A6AA.AC1E.01.11.0F.B4BB  read catalog sector
         A2F8.A6AA.02.11.0F.B4BB  write catalog sector
         AD1A.AB45.01.11.00.B3BB  read VTOC
         AB45.B1E6.01.11.0F.B4BB  read catalog sector
         A6AA.AD1A.01.1F.0F.9700  read T/S list
         A6AA.AD1D.01.1F.0E.9600  read 4 data sectors
         A6AA.AD1D.01.1F.0D.9600    to VERIFY the file
         A6AA.AD1D.01.1F.0C.9600
         A6AA.AD1D.01.1F.0B.9600
         :$800G                   dis-install SNOOPER

      1000 *SAVE S.RWTS.SNOOPER
      1010 *--------------------------------
      1020 PRBYTE .EQ $FDDA
      1030 CROUT  .EQ $FD8E
      1040 COUT   .EQ $FDED
      1050 *--------------------------------
      1060 INSTALL.SNOOPER
      1070        LDX #1
      1080 .1     LDA DRIVER,X
      1090        PHA
      1100        LDA $B091,X
      1110        STA DRIVER,X
      1120        PLA
      1130        STA $B091,X
      1140        DEX
      1150        BPL .1
      1160        RTS
      1170 *--------------------------------
      1180 DRIVER .DA SNOOPER  MODIFIED DURING OPERATION
      1190 *--------------------------------
      1200 SNOOPER
      1210        LDA $778
      1220        STA SAVE778
      1230        LDA $7F8
      1240        STA SAVE7F8
      1250 *--------------------------------
      1260        TSX
      1270        JSR CROUT
      1280        JSR PRADDR   PRINT RETURN ADDR FROM STACK
      1290        JSR PRADDR   AND ANOTHER ONE
      1300 *--------------------------------
      1310        LDA $B7F4    COMMAND
      1320        JSR BYTE
      1330        LDA $B7EC    TRACK
      1340        JSR BYTE
      1350        LDA $B7ED    SECTOR
      1360        JSR BYTE
      1370        LDA $B7F1    BUFFER ADDRESS
      1380        JSR PRBYTE
      1390        LDA $B7F0
      1400        JSR PRBYTE
      1410 *--------------------------------
      1420        LDA SAVE778
      1430        STA $778
      1440        LDA SAVE7F8
      1450        STA $7F8
      1460        LDA $AAC2
      1470        LDY $AAC1
      1480        JMP (DRIVER)
      1490 *--------------------------------
      1500 PRADDR
      1510        LDA $108,X
      1520        JSR PRBYTE
      1530        LDA $107,X
      1540        DEX          SET UP FOR NEXT ADDRESS
      1550        DEX
      1560 BYTE   JSR PRBYTE
      1570        LDA #"."
      1580        JMP COUT
      1590 *--------------------------------
      1600 SAVEX  .BS 1
      1610 SAVEY  .BS 1
      1620 SAVE778 .BS 1
      1630 SAVE7F8 .BS 1
      1640 *--------------------------------

Feedback about the latest Sieve | Peter J. McInerney

So the Sieve lives! Bob's article last month misses some of the facts, however. He states that my improved 68000 version on my 12.5 MHz DTACK Grounded board ran in .4 seconds; the actual time was .33 seconds. This is proportional to the .49 seconds claimed in the later Byte article for an 8 MHz 68000. My DTACK Grounded board uses 120 nanosecond static RAM and runs at a full 12.5 MHz speed (DTACK grounded means that the processor CANNOT wait for memory).

Hal Hardenburgh (editor of the now sadly no more DTACK newsletter and no slouch when it comes to assembly programming on the 68000) produced his own version of the original algorithm, essentially hand-compiled BASIC since that was what he wanted to compare to, and that ran in 1.29 secs for 10 iterations on a 10MHz board.

My faster 68000 sieve was my first 68000 program, so in light of my now more extended experience I tried to tighten it up even further. The result runs in .28 seconds for ten iterations on my DTACK board, and .72 seconds on a Macintosh. The main speed improvement comes from loading two extra registers for comparisons rather than doing CMPI's. The use of MOVEM for clearing the array was pointed out to me by Hal Hardenburgh and accounts for about .02 secs saved, at the expense of a large amount of elegance (oh well, what price aesthetics?).

In trying to guess the comparisons of the 65816 systems of the future with existing 68000 systems, two questions come to mind. First, if 6 or 8 MHz 65816s become available in quantity, how fast will the memory have to be to keep up? The 68000 can automatically adjust for slower memories, but is this true of the 65816? Second, and more importantly, is the question of memory addressing.

I wrote a version of the sieve that sifts the first 262143 integers. This took 13.5 seconds for 10 iterations on a Macintosh (this should equate to 5.3 seconds on my DTACK board, but I don't have enough memory to test it.) The program is only minimally different from the original (some constants changed and some address modes changed from word to long.)

How about writing a 65816 program to handle this large of an array? How much extra baggage is required to test page boundaries, move base addresses, etc? My point is that the restriction of 64K banks can really hurt in accessing large data arrays. Memory is getting cheaper all the time, so using more bytes for a 68000 program may well be no penalty, compared with the extra difficulty of writing 65816 code to handle large amounts of data.

Paint Yourself into the Corner | Adam Levin

I think I have come up with an interesting puzzle. Pretend that your Apple has only 48K of RAM: no ROM, no soft switches, no memory cards, just 48152 bytes of contiguous RAM from $0000 through $BFFF. Now, write a program which will store one number (of your choosing) into each and every one of these 49152 locations. The stumper here is creating a program which can overwrite itself completely, and which will not go running off through the I/O area causing disks to spin, etc.

There are certain limitations to actually implementing this on an Apple. When you hit <RESET> to examine the contents of memory after running your program, memory will be changed before you can look at it. It is unavoidable that page zero, the stack, and text screen memory will all get disrupted as soon as <RESET> is pressed. You still need to include these areas in your program, but you just will not be able to check them.

You will have to figure out some way of stopping the program before it runs off into the $Cxxx space. I decided to accept this limitation by allowing three bytes at $BFFD-F to contain a JMP instruction, not stuffing my favorite number in them. So my solution actually only stuffs my number into $0000-$BFFC.

Bob Sander-Cederlof has a solution that stuffs the same number in every byte from $0000 through $BFFF, but depends on two locations in the I/O area to stop the program from rampaging around $Cxxx space.

Try your hand at this puzzle! Next month we'll show some of the best solutions.

## INDEX

### Apple Assembly Line, Volume 5

### October, 1984 through September, 1985

    AAAA

    Applesoft
      A CALL Utility for Applesoft....................David Johnson... 6/85/24-27
      Correction to Line Number XREF....................Bill Morgan...10/84/18
      Double Precision Arithmetic
             ...see Double Precision Floating Point Package
      Fast Text Windows for Applesoft.................Michael Ching... 4/85/16-20
      80-Column Window Utility for //e and //c............Bill Reed... 5/85/11-15

    BBBB

    Benchmarks
      Prime Benchmark for the 65802.........................Bob S-C... 9/85/2-9
    Book Reviews
      "Apple II+/IIe Troubleshooting & Repair Guide"..................11/84/1
      "Apple ProDOS:  Advanced Features for Programmers".............. 5/85/18-19
      "Applevisions".................................................. 6/85/21
      "Assembly Language for the Applesoft Programmer"................ 2/85/20
      "Enhancing Your Apple II and //e, vol. 2"....................... 5/85/1
      "Inside the Apple //c".......................................... 4/85/7
      "Inside the Apple //e"..........................................12/84/16-18
      "Open Apple"....................................................12/84/1
      Out of Print..........................................Bob S-C...10/84/16
    The Boyer-Morris String Search Algorithm............Bob Bernard... 6/85/2-12
    Buffering
      //c + Z-RAM = 576K Printer Buffer...............David Johnson... 8/85/2-10

    CCCC

    Conversions
      Convert Two Decimal Digits to Binary..................Bob S-C...11/84/15-16
      Generic Conversion Routines...........................Bob S-C... 8/85/17-21
      Improving the Single-Byte Converter................Bruce Love... 6/85/21
      Short Binary-Decimal Conversion in 65802..............Bob S-C... 9/85/24-28
      Short Single-Byte Hex-to-Decimal Printer..............Bob S-C... 1/85/31-32
      Sly Hex Conversion....................................Bob S-C...12/84/21-22
    Corrections
      Correction to DP18, part 5......................Paul Schlyter...10/84/10
      Correction to Line Number XREF....................Bill Morgan...10/84/18
      Correction to Symbol Table Source Maker...............Bob S-C... 2/85/25
      Improvements to 80-Column Monitor Dump..........Jan Eugenides...11/84/22-23
    Cross Assemblers
      6800/6801/6301 Cross Assembler Version 2.0...................... 1/85/1
      6800/6801/6301 Cross Assembler ProDOS........................... 8/85/1
      An 8086/8088 Cross Assembler....................Don Rindsberg... 4/85/21

    DDDD

    Disassemblers
      Adapting the Output Format of RAK-Ware DISASM......Bob Kovacs... 5/85/21-22
      A Disassembler for the 65816..........................Bob S-C... 3/85/20-28
      Generating Cross Reference Text File with DISASM...Bob Kovacs...11/84/23
      How Many Bytes for Each Opcode?.......................Bob S-C... 8/85/12-16
    DOS Enhancements and Patches
      Improved DOS 3.3 Number Parsing & Lower-Case Commands.Bob S-C... 3/85/15-18
      Making DOS-Less Disks.................................Bob S-C... 2/85/21-25
      New Catalog for DOS 3.3.....................Robert F. O'Brien... 5/85/2-11
      New Catalog Revisited.......................Robert F. O'Brien... 7/85/32
      Put DOS and ProDOS Files on the Same Disk.............Bob S-C... 9/85/11-20
      Reading DOS 3.3 Disks with ProDOS.....................Bob S-C... 7/85/2-14
      Shortening the DOS File Buffer Builder................Bob S-C... 3/85/2-9
      A Solution to Overlapping DOS Patches..............Paul Lewis...12/84/27
      Volume Catalog for Corvus and Sider...................Bob S-C... 4/85/9-11
      Wildcard Filename Search..............................Bob S-C... 8/85/22-28
    Double Precision Floating Point Package
      Correction to DP18, part 5......................Paul Schlyter...10/84/10
      New DP18 Square Root Subroutine.......................Bob S-C...11/84/20-21
      Part 6, VAL, INT, ABS, SGN, and SQR Functions.........Bob S-C...10/84/2-9
      Part 7, LOG and EXP Functions.........................Bob S-C...11/84/2-13
      Part 8, Trig Functions................................Bob S-C...12/84/2-14
      Part 9, PRINT.........................................Bob S-C... 1/85/2-24
      Part 10, INPUT........................................Bob S-C... 2/85/2-14
      Some Final DP18 Subroutines...........................Bob S-C... 5/85/28

    GGGG

    Graphics
      Building Hi-Res Pre-Shift Tables.............Gianluca Pomponi... 2/85/26-28
      Generating Tables for Faster Hi-Res...................Bob S-C...12/84/24-26
      Short Integer Square Root Subroutine..................Bob S-C... 6/85/13

    HHHH

    Hardware Reviews
      The Oki 6203 Multiply/Divide Chip.....................Bob S-C... 3/85/19
      Review of the FCP Hard Disk (The Sider)...............Bob S-C... 4/85/27-28
      Review of the M-c-T SpeedDemon........................Bob S-C... 7/85/16-22
      A Whole Megabyte for Your Apple //e...................Bob S-C...11/84/18
      Write Guard Disk Modification Kit............................... 2/85/19

    IIII

    Interrupt Trace...............................Charles H. Putney... 6/85/16-20

    MMMM

    Macro Information by Example....................Sandy Greenfarb...11/84/24-25
    Monitor Enhancements and Patches
      Two ROM Sets in One Apple //e.........................Bob S-C... 6/85/22-23

    NNNN

    New Product Announcements
      6800/6801/6301 Cross Assembler Version 2.0...................... 1/85/1
      6800/6801/6301 Cross Assembler ProDOS........................... 8/85/1
      Blind Word Processor............................................10/84/1
      S-C Macro Assembler Version 2.0.................................11/84/14
      S-C Macro Assembler Version 2.0 DOS Source Code................. 9/85/1
      S-C Macro Assembler ProDOS...................................... 6/85/1

    PPPP

    Prime Benchmark for the 65802...........................Bob S-C... 9/85/2-9
    ProDOS
      Allow BSAVE to New Non-Binary Files in BASIC.SYSTEM.........
                                                 ......Mark Jackson... 7/85/30-31
      DATE Command for ProDOS...........................Bill Morgan... 5/85/23-32
      Finding Memory Size in ProDOS.........................Bob S-C... 3/85/28
      Multi-Level ProDOS Catalog............................Bob S-C... 7/85/23-30
      Put DOS and ProDOS Files on the Same Disk.............Bob S-C... 9/85/11-20
      Reading DOS 3.3 Disks with ProDOS.....................Bob S-C... 7/85/2-14
      Shrinking Code Inside ProDOS..........................Bob S-C... 4/85/12-14

    RRRR

    Remembering When........................................Bob S-C...12/84/23
    Reviews, see "Book Reviews", "Hardware Reviews", "Software Reviews"

    SSSS

    S-C Macro Assembler
      32-bit Values in Version 2.0 -- A Mixed Blessing......Bob S-C... 5/85/32
      AUTO/MANUAL Toggle Update for Version 2.0...Robert F. O'Brien... 5/85/15-16
      Patches for Time/Date in Titles....................R. M. Yost... 2/85/18
      Putting S-C Macro on a QuikLoader Card..........Jan Eugenides... 4/85/2-7
      Questions and Answers........................................... 2/85/16-18
      Reading DOS 3.3 Disks with ProDOS.....................Bob S-C... 7/85/2-14
      S-C Macro Assembler Version 2.0...................Bill Morgan...11/84/14
      Symbol Table Source Maker......Peter McInerney and Bruce Love... 1/85/25-30
      USR Command to List Major Labels Only.................Bob S-C... 4/85/24-27
      Videx UltraTerm Driver.......................................... 3/85/1
      Videx VideoTerm Driver Revision................................. 7/85/1
    Searching
      Boyer-Morris String Search Algorithm..............Bob Bernard... 6/85/2-12
      Wildcard Filename Search..............................Bob S-C... 8/85/22-28
    Software Reviews
      Blankenship's BASIC...................................Bob S-C...12/84/26
      Macintosh Assemblers...............................Lane Hauck...10/84/24-28
      Software Sources for the 65802 and 65816..............Bob S-C... 9/85/21-23
    String Search Algorithm, Boyer-Morris...............Bob Bernard... 6/85/2-12
    Symbol Table Source Maker........Peter McInerney and Bruce Love... 1/85/25-30
      Correction to Symbol Table Source Maker...............Bob S-C... 2/85/25

    TTTT

    Techniques
      The Boyer-Morris String Search Algorithm..........Bob Bernard... 6/85/2-12
      Building Hi-Res Pre-Shift Tables.............Gianluca Pomponi... 2/85/26-28
      Even Trickier "Index to Masks"......
                 ......Charles Putney, Bruce Love, and David Eisler...10/84/9-10
      Generating Tables for Faster Hi-Res...................Bob S-C...12/84/24-26
      Making DOS-Less Disks.................................Bob S-C... 2/85/21-25
      Short Integer Square Root Subroutine..................Bob S-C... 6/85/13
      Strange Way to Divide by 7............................Bob S-C...12/84/19-20
      Turning Bit-Masks into Indices........................Bob S-C...11/84/26-28
    Two ROM Sets in One Apple //e...........................Bob S-C... 6/85/22-23

    UUUU

    Utility Programs
      A CALL Utility for Applesoft....................David Johnson... 6/85/24-27
      A Disassembler for the 65816..........................Bob S-C... 3/85/20-28
      Interrupt Trace.............................Charles H. Putney... 6/85/16-20
      Making DOS-Less Disks.................................Bob S-C... 2/85/21-25
      Multi-Level ProDOS Catalog............................Bob S-C... 7/85/23-30
      Put DOS and ProDOS Files on the Same Disk.............Bob S-C... 9/85/11-20
      Reading DOS 3.3 Disks with ProDOS.....................Bob S-C... 7/85/2-14
      Symbol Table Source Maker......Peter McInerney and Bruce Love... 1/85/25-30

    VVVV

    Volume Catalog for Corvus and Sider.....................Bob S-C... 4/85/9-11

    WWWW

    Wildcard Filename Search................................Bob S-C... 8/85/22-28

    65C02

    65C02s in Old Apples.................................Jim Sather... 3/85/10-14
    More on Using 65C02's in Old Apples..............Andrew Jackson...12/84/15

    65802/65816

      The 65802 is Here!....................................Bob S-C...10/84/12-16
      65816 News........................................Bill Morgan...11/84/19
      Correction re MVN and MVP in 65802....................Bob S-C...12/84/18
      A Disassembler for the 65816..........................Bob S-C... 3/85/20-28
      How Many Bytes for Each Opcode?.......................Bob S-C... 8/85/12-16
      Note on the TXS Instruction in the 65802..............Bob S-C... 6/85/14-15
      A Powerful 65816 Board on the Horizon.................Bob S-C... 4/85/22-23
      Prime Benchmark for the 65802.........................Bob S-C... 9/85/2-9
      Problems with 65802's in Apple II+....................Bob S-C... 9/85/23
      Short Binary-Decimal Conversion in 65802..............Bob S-C... 9/85/24-28
      Shortening the DOS File Buffer Builder................Bob S-C... 3/85/2-9
      Software Sources for the 65802 and 65816..............Bob S-C... 9/85/21-23

Multiple Column Dis-Assembly | Adam Levin

When I'm writing and debugging a program, I always use a lot of printer paper as I list and re-list version after version of my creation. Using the Apple monitor's 'L' command wastes a lot of that paper, too. Since each disassembled line takes at most 36 characters, I end up wasting half of each page!. I know I could feed the paper through a second time with the right hand side now on the left, but the left hand listing isn't always the same length as the right, so I end up with listings that span several separate lengths of paper. I've written a program to solve this dilemma (as if you hadn't guessed!), and I call it PolyCol.

PolyCol will be of use no matter what type of printer you have: daisywheel printer and 80-column video card owners will get two columns per page (screen), 80-column dot matrix owners can get up to four columns per page by using compressed printing, and those with wider carriages can get even more! In addition, by compressing the print size vertically as well, it is possible to get a disassembly of all the ROMs in the Apple onto only 16 pages! (It's also possible to go blind trying to read it!)

Note that rather than creating all the text in memory, and then dumping an entire page at once, PolyCol calculates which opcode to disassemble where, 'on-the-fly'. You might think that this would slow things down appreciably; but in fact unless you require tens of columns, the listing is done relatively quickly.

As you will see from the listing, seven zero-page locations are used to hold the parameters which the user must specify. You must store the starting and ending addresses of the area to be dis-assembled into locations $00-03. Locations $04-07 control the number of lines per page and columns per line, as well as several other features. Here are some examples to show what you can do with different parameter settings:

         $04  $05  $06
         ---  ---  ---

         $01  $14  $FE  - Standard monitor 'L' listing.
                          Press any key to see the next page.

         $02  $36  $FF  - Two column, 54 line page with a form feed
                          in between pages

         $04  $4C  $0C  - Four column, 76 line page with 12 spaces
                          between pages.  Don't forget to set
                          elite typeface and compressed print.

         $04  $70  $FF  - Four column, 112 lines per page!
                          To do this I had to use compressed
                          elite super- script, with a line
                          spacing of 1/12th in.

You can add just a little code to POLYCOL to set it up as a control-Y command. Then you could set the starting and ending addresses as in normal monitor commands. The other four parameters could also be specified in the control-Y command format, if you really get serious about modifications.

      1000 *SAVE S.POLYCOL
      1010 *--------------------------------
      1020 *  PolyCol
      1030 *  Produces multi-column Apple monitor dis-assemblies.
      1040 *  Copyright (c) 1986 Adam Levin
      1050 *--------------------------------
      1060        .OR $800
      1070 *---User parameters--------------
      1080 STRTL  .EQ $00      Starting address
      1090 STRTH  .EQ $01
      1100 ENDL   .EQ $02      Ending address
      1110 ENDH   .EQ $03
      1120 NCPP   .EQ $04      # Columns per page
      1130 *                     (0 <= NCPP <= FF)
      1140 *                     (each column takes 34 chars.)
      1150 NLPP   .EQ $05      # Lines printed per page
      1160 *                     (0 <= NLPP <= FF)
      1170 NSKP   .EQ $06      # Blank lines between pages
      1180 *                     (0 <= NSKP <= FF)
      1190 *                     (FF = Form feed)
      1200 *                     (FE = pause between pages)
      1210 SLOT   .EQ $07      Slot # to direct output to
      1220 *                     (0 <= SLOT <= 7)
      1230 *                     (0 = use currently active device)
      1240 *---Program variables------------
      1250 BRUNFX .EQ $08      Holds the DOS stack pointer
      1260 TOFARL .EQ $09      Adrs of 1st opcode in col 2;
      1270 TOFARH .EQ $0A      1st column ends just before it.
      1280 TCSWL  .EQ $0B      Holds the 'other' CSWL address
      1290 TCSWH  .EQ $0C
      1300 COLCNT .EQ $0D      Current column
      1310 TEMPL  .EQ $0E      Temporary storage
      1320 TEMPH  .EQ $0F          "        "
      1330 *---Monitor variables-------------
      1340 FORMAT .EQ $2E      Holds addressing mode code
      1350 CSWL   .EQ $36      Character Output SWitch Low address
      1360 CSWH   .EQ $37          "       "      "    High   "
      1370 PCL    .EQ $3A      Adrs of opcode currently being
      1380 PCH    .EQ $3B      dis-assembled.
      1390 STKPTR .EQ $AA59    DOS 3.3 stack pointer save loc't'n
      1400 KBD    .EQ $C000    Keyboard
      1410 STROBE .EQ $C010    Clear keyboard strobe
      1420 *---Monitor ROM Subroutines------
      1430 INSDS2 .EQ $F88C    Formats each disassembly line
      1440 INSTDSPA .EQ $F8D3  Print opcode & operand
      1450 PRBL2  .EQ $F94A    Prints (X-reg) many blank spaces
      1460 PCADJ  .EQ $F953    Adjusts A,Y (PCL,H) after each line
      1470 RDKEY  .EQ $FD0C    Get an input character
      1480 CROUT  .EQ $FD8E    Print a <RETURN>
      1490 PRYX2A .EQ $FD99    Print 'adrs-'
      1500 COUT   .EQ $FDED    Print Acc as a character
      1510 *---Macro definitions------------
      1520        .MA CMPD     Double byte CMP
      1530        LDA ]1       From the S-C
      1540        CMP ]2       MACRO LIBRARY file.
      1550        LDA ]1+1
      1560        SBC ]2+1
      1570        .EM
      1580 *
      1590        .MA MOVD     Double byte MOV
      1600        LDA ]1
      1610        STA ]2
      1620        LDA ]1+1
      1630        LDA ]2+1
      1640        .EM
      1650 *
      1660        .MA MSG      MESSAGE PRINT MACRO
      1670        LDX #]1
      1680        JSR PRINT.MESSAGE
      1690        .EM
      1700 *---------------------------------
      1710 POLYCOL
      1720        LDA STKPTR   Save stack pointer now,
      1730        STA BRUNFX   restore it at the end.
      1740        LDA SLOT     Send the output to another device?
      1750        BEQ .1       No.
      1760        ORA #$C0     Use $Cn00 (n=SLOT) so we can simulate a
      1770        LDX #0       PR#n when we swap CSWL,H & TCSWL,H.
      1780        BEQ .2       This creates a problem if SLOT <> 0 &
      1790 .1     LDA CSWH     SLOT contains an 80-col card since PR#
      1800        LDX CSWL     can activate card, but not de-activate.
      1810 .2     STA TCSWH    No harm done, but it can be confusing.
      1820        STX TCSWL
      1830        JMP PAUSE2   Start out by waiting for a keypress.
      1840 *--------------------------------
      1850 STRT   LDA NLPP     'CALC' NLPP lines from STRTL,H.
      1860        STA TEMPL    Adrs of the opcode just after the last
      1870        LDA #0       one in column one.  Store in TOFARL,H
      1880        STA TEMPH    to keep STRTL,H from going beyond it.
      1890        JSR CALC
      1900        >MOVD PCL,TOFARL
      1910 COLM1  LDA #1       Always start in column one.
      1920        STA COLCNT   Set COLCNT to 1
      1930        >CMPD ENDL,STRTL   Have we finished?
      1940        BCS NOESC    No, ENDL,H >= STRTL,H
      1950        JSR CROUT    Yes, purge last printed line.
      1960 ESC    JSR SWAP     <ESC> brings you here, too.
      1970        >MSG M.BYE   Print end message.
      1980        LDA BRUNFX   Restore the stack pointer
      1990        STA STKPTR
      2000        RTS          All done.
      2010 NOESC  >CMPD STRTL,TOFARL  About to pass col 2?
      2020        BCC NULINE   No, so continue
      2030        LDX NCPP     Yes, so find the new first
      2040        JSR MULT     line for the new first column.
      2050        JSR CALC
      2060        >MOVD PCL,STRTL
      2070 NUPAGE LDX NSKP     Page breaks
      2080        CPX #$FE
      2090        BEQ PAUSE    Pause
      2100        BCS FRMFD    Form feed
      2110        CPX #0
      2120 .1     BEQ STRT     No break - solid listing
      2130        JSR CROUT    Yes, print NSKP lines
      2140        DEX
      2150        JMP .1
      2160 *--------------------------------
      2170 FRMFD  LDA #$8C
      2180        JSR COUT
      2190        JMP STRT
      2200 *--------------------------------
      2210 PAUSE  JSR CROUT    Print a <RETURN>
      2220        JSR SWAP     Swap TCSWL,H & CSWL
      2230 PAUSE2 >MSG M.PAUSE Print PAUSE msg
      2240        JSR RDKEY
      2250        JSR SWAP     Swap back
      2260        JMP STRT     Do it all again
      2270 *--------------------------------
      2280 NULINE JSR CROUT    Print a <RETURN>
      2290        LDA KBD      A key might have been pressed
      2300        EOR #$9B     It might have been <ESC>
      2310        BNE OFFSET   It wasn't; continue
      2320        BIT STROBE   It was!  ESCape!
      2330        JMP ESC
      2340 OFFSET LDX COLCNT   Compute which opcode to
      2350        JSR MULT     Disassemble next.
      2360        JSR CALC
      2370        >CMPD ENDL,PCL  Is adrs be beyond ENDL,H?
      2380        BCC NEXTOP   Yes, don't bother with it
      2390        LDX PCL      No, so disassemble it
      2400        LDY PCH
      2410        JSR PRYX2A   Print the opcode address
      2420        LDX #1
      2430        JSR PRBL2    Print 1 blank.  Monitor puts three
      2440 *                   here, but if each column is no more
      2450 *                   than 34 chars long, can fit 4 columns
      2460 *                   onto a printer with 132 chars/line.
      2470        JSR INSDS2   Format it
      2480        JSR INSTDSPA   Print it
      2490        LDA COLCNT   If last column, don't pad.
      2500        CMP NCPP
      2510        BEQ NXTCOL   It is, get out
      2520        LDX #0       Isn't, so pad with blanks so that each
      2530 *                   column takes exactly 34 characters.
      2540        JSR INSDS2   Calculate the format code
      2550        LDX #10      ASSUME 10 SPACES
      2560        LDA FORMAT   Get it
      2570        BEQ SPACE    1 byte code requires 10 spaces
      2580        LDX #7       ASSUME 7 SPACES
      2590        CMP #$81     Z-page
      2600        BEQ SPACE
      2610        DEX          ASSUME 6 SPACES
      2620        CMP #$21     Immediate
      2630        BEQ SPACE
      2640        DEX          ASSUME 5 SPACES
      2650        CMP #$82     Absolute
      2660        BEQ SPACE    5 SPACES
      2670        CMP #$85     Zpage,Y
      2680        BEQ SPACE    5 SPACES
      2690        CMP #$91     Zpage,X
      2700        BEQ SPACE    5 SPACES
      2710        CMP #$9D     Relative
      2720        BEQ SPACE    5 SPACES
      2730        LDX #3       All others
      2740 SPACE  JSR PRBL2    Print (X-reg) many blanks
      2750 NXTCOL INC COLCNT   Go to next column
      2760        LDA NCPP
      2770        CMP COLCNT   Have we gone too far?
      2780        BCS OFFSET   No, do OFFSET
      2790 NEXTOP LDA #1       Jump over the line
      2800        STA TEMPL    just done.
      2810        LDA #0
      2820        STA TEMPH
      2830        JSR CALC
      2840        >MOVD PCL,STRTL    Store it in STRTL,H
      2850        JMP COLM1    And do it all again
      2860 *---------------------------------
      2870 *  CALC returns the opcode adrs that is TEMPL,H
      2880 *       disassembled (!) lines from STRTL,H
      2890 *       It returns this address in PCL,H
      2900 CALC   >MOVD STRTL,PCL   Put STRTL,H into PCL,H for INSDS1
      2910 .1     LDA TEMPL    If TEMPL,H = 0 then done
      2920        ORA TEMPH
      2930        BEQ .3
      2940        LDX #0
      2950        JSR INSDS2   Get end of the next opcode & operand
      2960        JSR PCADJ    Get the new address from PCADJ
      2970        STA PCL      Store the resulting address in PCL,H
      2980        STY PCH
      2990        LDA TEMPL    DEC TEMPL,H - with help
      3000        BNE .2       from the MACRO LIBRARY again!
      3010        DEC TEMPH
      3020 .2     DEC TEMPL
      3030        CLV          Exit from top of loop, not here
      3040        BVC .1       Always taken
      3050 .3     RTS
      3060 *--------------------------------
      3070 *  MULT returns (NLPP * n-1).  N is usually
      3080 *       COLCNT, and as such is usually a small
      3090 *       number (almost always smaller than NLPP).
      3100 *       So MULT simply adds NLPP to itself n times.
      3110 *       Returns with result in TEMPL,H
      3120 MULT   LDA #0       Zero TEMPL,H
      3130        STA TEMPL
      3140        STA TEMPH
      3150 .1     CLC
      3160 .2     DEX          Exit loop from top, so call with n+1
      3170        BEQ .3       Anything times 0 equals 0
      3180        LDA TEMPL    Add NLPP to TEMPL,H
      3190        ADC NLPP
      3200        STA TEMPL
      3210        BCC .1       ...NO CARRY, KEEP ADDING
      3220        INC TEMPH    ...CARRY
      3230        BCS .1       ...ALWAYS
      3240 .3     RTS
      3250 *--------------------------------
      3260 SWAP   LDA CSWL     Swap output device adrses.  They are
      3270        LDX TCSWL    the same if SLOT = 0, but swap anyway.
      3280        STX CSWL
      3290        STA TCSWL
      3300        LDA CSWH
      3310        LDX TCSWH
      3320        STX CSWH
      3330        STA TCSWH
      3340        RTS
      3350 *--------------------------------
      3360 PM.1   JSR COUT
      3370        INX
      3380 PRINT.MESSAGE
      3390        LDA MSGS,X
      3400        BMI PM.1
      3410        RTS
      3420 *--------------------------------
      3430 MSGS
      3440 M.PAUSE    .EQ *-MSGS
      3450        .AT -'PRESS A KEY '
      3460 M.BYE      .EQ *-MSGS
      3470        .AT -'*** END OF LISTING '
      3480 *--------------------------------

Apple Manuals from Addison-Wesley | Bill Morgan

Those elusive Apple technical manuals are finally coming out of hiding! As we reported some months ago, Addison-Wesley is beginning to distribute Apple's manuals, and we can now supply them for you. The ones we have seen are at least as good as Apple's own editions, and in some cases better.

Here are the titles that we can order for you:

Applesoft Tutorial - $29.95, disk. Beginner's introduction to Applesoft, with a disk of examples.

Applesoft BASIC Programmer's Reference Manual - $22.95, 373+xxv pages. Complete reference manual for Applesoft, documenting all features with many examples.

BASIC Programming with ProDOS - $29.95, 264+xxix pages, disk Covers using ProDOS from BASIC, including command and file handling. The disk includes lots of examples, and the useful Applesoft Programmer's Assistant program, which includes RENUMBER, MERGE, AUTOmatic line numbering, REM deletion, variable cross reference, and other features.

And here are the ones that look most important, that we expect to keep in stock here at S-C:

Apple //e Technical Reference manual - $24.95, 409+xxxii pages. Here's Apple's documentation of all the internals of the //e, including I/O devices and firmware, memory organi- zation, the System Monitor, peripheral-card programming, the Super Serial Card, and hardware implementation. The new edition includes all the new features of the Enhanced //e and a complete source listing of the ROMs. This book is essential for serious //e programming.

Apple //c Technical Reference Manual - $24.95. And here is the same detailed coverage of the //c, and more. Additional topics documented in this book are the built-in serial I/O ports, the mouse input, and interrupt handling. If you want to use these features of the //c, get this book.

ProDOS Technical Reference Manual- $29.95, 186+xvii pages, disk. This is the official book on ProDOS, covering files, MLI calls, System programs, interrupt handling, and more. The disk is the ProDOS Exerciser, which allows you to experiment with all of the MLI calls without writing special programs. This book completes a ProDOS programmer's reference shelf, along with Beneath Apple ProDOS, and Apple ProDOS: Advanced Features.

The //e manual was scheduled for July publication: we just received it and the ProDOS manual today. The //c manual is scheduled for November delivery: we'll accept orders and ship the book as soon as A-W comes through.

Many thanks to Apple and to Addison-Wesley for making these important documents so easily available.

Now That You Know Apple Assembly Language, What Can You Do With It? | Review by Bill Morgan

Do you know the difference between LDA LABEL,X and LDA (LABEL),Y but wonder when to use which? Are you confused by the way PHA, PHA, RTS doesn't go home, but jumps somewhere else entirely? Do you know what the 6502 opcodes do, but still feel lost when it comes time to combine them into a program?

Jules Gilder, a long-time contributor to several of the Apple Magazines, has written a book just for you. He spends about 190 pages covering the intermediate level of assembly language programming in the Apple II computer. His programs are very well commented, and the accompanying text contains almost a line-by-line discussion of how and why each program works.

Gilder concentrates on the Apple-specific features of 6502 programming: input and output hooks, the internal speaker, and basic linkage to Applesoft. This combination should make this book especially appealing to those of you who have learned 6502 from a "generic" book and want to find out how to apply your new knowledge to your Apple II's.

Here is a summary of each chapter of Now That You Know...:

1) Before You Get Started -- This is an introduction to assemblers and their conventions.

2) Getting Information out of Your Computer -- This chapter covers simple output, including message printing and decimal number display.

3) Getting Information into Your Computer -- Here we get into reading keystrokes and lines, handling decimal input, and also menu control structures.

4) Stealing Control of the Output -- This one goes into taking over the output hook to do custom printer setup codes and drivers, output filtering, and formatting.

5) Stealing Control of the Input -- Learn how to grab the input hook to add a custom cursor, numeric keypad, an in-memory EXEC simulator, an Applesoft keyboard macro facility, and a lower-case input driver using the shift-key modification.

6) Using Sound in Your Programs -- How to use the Apple's built-in speaker to create a variety of sounds.

7) Learning to Use the Ampersand -- Here are techniques for hooking into the &-vector to do hexadecimal input and output in Applesoft, find a program line in memory, append two Applesoft programs, and revive a program lost by the NEW command.

8) Expanding Applesoft BASIC -- Now we can have computed GOTO, GOSUB and LIST, do double-byte PEEKs and POKEs, switch between two Applesoft programs sharing memory and variables, and add function keys to control output modes.

The only real weakness in this book is the complete lack of attention to the Apple's graphic display possibilities, and comparatively little coverage of dealing with DOS (and only one small appendix covering conversion to ProDOS.) I suppose Gilder regards these as more advanced topics. Hopefully he will see fit to focus on such subjects in a future book.

Gilder's company, Redlig Sytems, Inc., also has diskettes of all the programs in the book, in either source or object form.

We'll be carrying Now That You Know... for only $18 + shipping.

Apple Software Protection Digest

Gilder is also starting a newsletter on the subject of Apple software protection. This publication is devoted both to protecting your own programs and defeating the protection on others'. Here is part of Jules' description:

> Apple computer owners need a place where they can get more information about software protection. They need a forum where they can exchange ideas with others who face the same or similar problems. They need to know what software protection is, how it's implemented, what are the consequences of it, how it can be overcome if necessary and if there are any comparable unprotected alternatives to particular protected software packages.

> Apple Software Protection Digest will provide you with this information and more. It will show you new ways to protect, unprotect and backup your programs. It will teach you how to prevent others from accessing your programs and it will show you how to make them more difficult to copy. In addition, you'll learn how to overcome these and other protection schemes that are in use. You'll learn how to use the powerful, but compli- cated nibble copy programs. You'll also learn how to crack or remove protection entirely from many programs.

In the first issue he covers hiding Applesoft program lines (and finding them once they're hidden), making a machine language program automatically execute when BLOADed, protecting a disk by adding extra tracks and leaving some tracks unformatted, backing up The Print Shop, and he reviews the Copy II Plus nibble copier.

As a special offer for AAL subscribers, Gilder will give you a free copy of the first issue of Apple Software Protection Digest. Just send your name and address to Redlig Systems, Inc., 2068) 79th St., Brooklyn, NY, 11214. Be sure to mention that you are an AAL reader. The subscription rate is $24 for one year, or $42 for two years.

Apple Assembly Line is published monthly by S-C SOFTWARE CORPORATION, P.O. Box 280300, Dallas, Texas 75228. Phone (214) 324-2050. Subscription rate is $18 per year in the USA, sent Bulk Mail; add $3 for First Class postage in USA, Canada, and Mexico; add $14 postage for other countries. Back issues are available for $1.80 each (other countries add $1 per back issue for postage).

All material herein is copyrighted by S-C SOFTWARE CORPORATION, all rights reserved. (Apple is a registered trademark of Apple Computer, Inc.)