Apple Assembly Line
Volume 7 -- Issue 12September 1987

In This Issue...

Gary Little's new book is finally here: "Exploring the Apple IIgs", published by Addison-Wesley, 534 pages. If you are seriously trying to conquer the IIgs in assembly language, this book is a must. Instead of just telling us the tool numbers, Gary includes working examples of assembly language code which use the tools. Here is a list of the chapter titles, which I think is the easiest way to describe the contents:

  1. Exploring the Apple IIgs
  2. Programming the 65816 Microprocessor
  3. Using the GS Tools
  4. Memory Management
  5. Event Management
  6. Windows and Graphics
  7. Using Pull-Down Menus
  8. Using Dialog and Alert Boxes
  9. All about Desk Accessories
  10. The ProDOS-16 Operating System
  11. Sound and Music
  12. Using the Text Tool Set

The examples are all written using Apple's APW assembler, and make extensive use of the toolbox macros included with that assembler. A coupon in the back of the book lets you order a complete source code disk directly from Gary Little for all of the programs listed in the book for only $20. You can buy the book from us for $21 plus shipping.

Another new book this month is also from Addison-Wesley, in the official Apple IIgs series, "The Apple IIgs Hardware", 288 pages + 8 foldout schematics. This one lists at $24.95, and you can get it from us for $23. Again, if you are serious about programming the IIgs in assembly language you probably need this book. It contains information about the hardware you won't find in the other books.


Draw Circles the Fast WayBob Sander-Cederlof

I loved the article "Vector-to-Raster Algorithms" by Dick Pountain in the September 1987 issue of BYTE. It is the kind of article that explains why I have been a loyal subscriber for ten years or so. Pountain carefully explains how the fundamental graphics subroutines are written, and gives pseudo-code examples for each one. And, wonder of wonders, BYTE printed all of the examples! (It has been so frustrating the last three years to find that the examples must be downloaded from BIX or ordered at extra cost!)

I decided to try my hand at coding a fast circle-drawing subroutine for Apple hi-res graphics. Things like that are already included in the //gs QuickDraw ToolBox for Super Hi-Res, but I am not aware of any generally available circle-drawers for ordinary hi-res.

Since I wrote the double lo-res article last month, I decided to first try adding a circle-drawer to that program. It would be somewhat easier, since all of the variables involved could be 8-bit integers. But even before that I decided to write an Applesoft version, using normal hi-res.

     1000  REM  DRAW A CIRCLE USING MICHENER'S ALGORITHM
     1010  HGR 
     1020  HCOLOR= 3
     1030  INPUT CX,CY,R
     1040 X = 0:Y = R:E = 3 - 2 * R
     1050  REM PLOT 8 POINTS
     1060  HPLOT CX + X,CY + Y: HPLOT CX + X,CY - Y
     1070  HPLOT CX - X,CY + Y: HPLOT CX - X,CY - Y
     1080  HPLOT CX + Y,CY + X: HPLOT CX + Y,CY - X
     1090  HPLOT CX - Y,CY + X: HPLOT CX - Y,CY - X
     1100  REM ADVANCE TO NEXT POINT
     1110  IF E > 0 THEN E = E + 4 * (X - Y) + 10:Y = Y - 1: GOTO 1130
     1120 E = E + 4 * X + 6
     1130 X = X + 1: IF X <  = Y THEN 1060
     1140  GOTO 1030

This program will draw a circle of radius R and center at CX,CY. Line 1030 lets you enter the center and radius. The algorithm actually computes an X-offset and Y-offset from the center for each point in 1/8th of the circle. Lines 1060-1090 use the offsets to plot eight points, one in each of the half-quadrants. The three expressions for calculating E, in lines 1040, 1110, and 1120 are the secret to the program. Pountain says they were derived by "algebraic re-arrangement" of the basic equation of a circle: X^2 + Y^2 = R^2. Maybe so, I'll just take his word for it.

I found it interesting to play with some of the parameters. I changed line 1030 do assign specific values to CX, CY, and R and then ask for a value "A". Then I changed the expression for "E" in line 1110 by substituting "A" in the place of "4". By changing the value of "A" I could draw anything from a square to a diamond with missing points. Try it!

Next I wrote the double lo-res version. The listing which follows can be appended to the listing on pages 7-10 in the August article. After assembly, executing the program named TC will clear the screen and draw four circles. They are drawn fast enough that they appear almost instantaneously.

Lines 3270-3330 define a macro named CIRCLE, which make it easy to call the CIRCLE subroutine. The three parameters are simply CX, CY, and R. SInce this is double lo-res, the legal limits will be small. CX may be 0 to 79, CY may be 0 to 47, and R may be 0 to 23. Any larger R-value would force part of the circle to go off the screen. I did not put in any error checking in this version, so if you do try to go off the edge you will probably clobber something. In my hi-res version I put in code to avoid plotting off the screen.

The code is basically a hand-compilation of the Applesoft version. The comments show the equivalent Applesoft statements.

  1000  .LIF
  1010 *SAVE S.DOUBLE LO-RES
  1020        .OP 65C02
  1030 *--------------------------------
  1040 X2     .EQ $2C
  1050 Y2     .EQ $2D
  1060 COLOR  .EQ $30
  1070 *--------------------------------
  1080 PLOT   .EQ $F800
  1090 SETCOL .EQ $F864
  1100 *--------------------------------
  1110        .MA FROM
  1120        LDA #]2      Y1
  1130        LDY #]1      X1
  1140        JSR SET.X1.Y1
  1150        .EM
  1160 *--------------------------------
  1170        .MA LINE.TO
  1180        LDA #]2      Y2
  1190        LDY #]1      X2
  1200        JSR LINE
  1210        .EM
  1220 *--------------------------------
  1230        .MA LINE
  1240        >FROM ]1,]2     X1,Y1
  1250        >LINE.TO ]3,]4  X2,Y2
  1260        .EM
  1270 *--------------------------------
  1280        .MA BOX.TO
  1290        LDA #]2      Y2
  1300        LDY #]1      X2
  1310        JSR BOX
  1320        .EM
  1330 *--------------------------------
  1340        .MA BOX
  1350        >FROM ]1,]2    X1,Y1
  1360        >BOX.TO ]3,]4  X2,Y2
  1370        .EM
  1380 *--------------------------------
  1390 T
  1400        JSR DLR      Turn on Double Lo-Res
  1410        JSR CLRTOP   Clear screen
  1420        LDA #15      Set Color = White
  1430        JSR SETCOL
  1440 *---DRAW DIAGONAL LINES----------
  1450        >LINE 0,0,39,39
  1460        >LINE 0,39,39,0
  1470        >LINE 79,39,40,0
  1480        >LINE 79,0,40,39
  1490 *---BOX 35,15 TO 44,24-----------
  1500        >BOX 35,15,44,24
  1510 *---BORDER AROUND SCREEN---------
  1520        >LINE 0,0,79,0
  1530        >LINE.TO 79,39
  1540        >LINE.TO 0,39
  1550        >LINE.TO 0,0
  1560 *--------------------------------
  1570 .2     LDA $C000
  1580        BPL .2
  1590        STA $C010
  1600 *--------------------------------
  1610        JSR TEXT
  1620        RTS
  1630 *--------------------------------
  1640 TEXT
  1650        STA $C051    TEXT
  1660        STA $C05F    SINGLE
  1670        STA $C054
  1680        RTS
  1690 *--------------------------------
  1700 DLR
  1710        LDA #$99
  1720        JSR $C300    TURN ON 80-COLUMN MODE
  1730        STA $C050    GRAPHICS
  1740        STA $C053    MIXED TEXT/GRAPHICS
  1750        STA $C054    START IN MAIN MEM
  1760        STA $C056    LO-RES
  1770        STA $C05E    DOUBLE
  1780        RTS
  1790 *--------------------------------
  1800 DPLOT.X1.Y1
  1810        LDA Y1
  1820        LDY X1
  1830 DPLOT  PHY
  1840        PHA          SAVE Y-COORD
  1850        TYA          X-COORD
  1860        LSR
  1870        TAY          X/2
  1880        PLA
  1890        PHA
  1900        BCS .1
  1910        STA $C055
  1920 .1     JSR PLOT
  1930        STA $C054
  1940        PLA
  1950        PLY
  1960        RTS
  1970 *--------------------------------
  1980 HLIN1  INY
  1990 HLIN   JSR DPLOT
  2000        CPY X2
  2010        BCC HLIN1
  2020        RTS
  2030 *--------------------------------
  2040 VLIN1  ADC #1
  2050 VLIN   JSR DPLOT
  2060        CMP Y2
  2070        BCC VLIN1
  2080        RTS
  2090 *--------------------------------
  2100 *   BOX   X2 IN Y, Y2 IN A
  2110 *--------------------------------
  2120 BOX    JSR SET.X2.Y2
  2130        LDA Y1
  2140 .1     LDY X1
  2150        JSR HLIN
  2160        CMP Y2
  2170        INC
  2180        BCC .1
  2190        RTS
  2200 *--------------------------------
  2210 CLRTOP LDA #0
  2220        STA COLOR
  2230 SETTOP >BOX 0,0,79,39
  2240        RTS
  2250 *--------------------------------
  2260 *   LINE FROM X1,Y1 TO X2,Y2
  2270 *         X2 IN Y, Y2 IN A
  2280 *--------------------------------
  2290 LINE   JSR SET.X2.Y2
  2300        LDX #1       First Y's, then X's
  2310 .1     LDY #0       START WITH SGN()=0
  2320        SEC
  2330        LDA X2,X     X2 or Y2
  2340        SBC X1,X     X1 or Y1
  2350        BEQ .3       VERTICAL or HORIZONTAL
  2360        BPL .2       Positive DELTA X or DELTA Y
  2370        DEY          Negative DELTA X or DELTA Y
  2380        EOR #$FF     2's Complement
  2390        INC
  2400        DEY          (overcome following INY)
  2410 .2     INY          SGN() = -1, 0, +1
  2420 .3     STA DX,X     DX or DY
  2430        TYA
  2440        STA SX,X     SX or SY
  2450        DEX
  2460        BPL .1
  2470 *--------------------------------
  2480        SEC
  2490        LDA DY
  2500        SBC DX       DY-DX
  2510        BPL .8       ...DX < DY
  2520        EOR #$FF     2'S COMPLEMENT
  2530        INC
  2540        STA D
  2550 .5     JSR DPLOT.X1.Y1
  2560        CLC
  2570        LDA X1
  2580        ADC SX
  2590        STA X1
  2600        SEC
  2610        LDA D
  2620        SBC DY
  2630        STA D
  2640        BEQ .6
  2650        BPL .7
  2660 .6     CLC          Y = Y + SY
  2670        LDA Y1
  2680        ADC SY
  2690        STA Y1
  2700        LDA D        D = D + DX
  2710        ADC DX
  2720        STA D
  2730 .7     LDY X1
  2740        CPY X2
  2750        BNE .5
  2760        LDA Y2
  2770        STA Y1
  2780        JMP DPLOT
  2790 *--------------------------------
  2800 .8     STA D
  2810 .9     JSR DPLOT.X1.Y1
  2820        CLC
  2830        LDA Y1       Y = Y + SY
  2840        ADC SY
  2850        STA Y1
  2860        SEC          D = D - DX
  2870        LDA D
  2880        SBC DX
  2890        STA D
  2900        BEQ .10      ...D = 0
  2910        BPL .11      ...D > 0
  2920 .10    CLC          X = X + SX
  2930        LDA X1
  2940        ADC SX
  2950        STA X1
  2960        LDA D        D = D + DY
  2970        ADC DY
  2980        STA D
  2990 .11    LDA Y1
  3000        CMP Y2
  3010        BNE .9
  3020        LDY X2
  3030        STY X1
  3040        JMP DPLOT
  3050 *--------------------------------
  3060 LIMIT.XY
  3070        CMP #40
  3080        BCC .1
  3090        LDA #39
  3100 .1     CPY #80
  3110        BCC .2
  3120        LDY #79
  3130 .2     RTS
  3140 *--------------------------------
  3150 SET.X1.Y1
  3160        JSR LIMIT.XY
  3170        STY X1
  3180        STA Y1
  3190        RTS
  3200 *--------------------------------
  3210 SET.X2.Y2
  3220        JSR LIMIT.XY
  3230        STY X2
  3240        STA Y2
  3250        RTS
  3260   .lin
  3270 *--------------------------------
  3280        .MA CIRCLE
  3290        LDA #]3      R
  3300        LDX #]1      CX
  3310        LDY #]2      CY
  3320        JSR CIRCLE
  3330        .EM
  3340 *--------------------------------
  3350 TC
  3360        JSR DLR      Turn on Double Lo-Res
  3370        JSR CLRTOP   Clear screen
  3380        LDA #15      Set Color = White
  3390        JSR SETCOL
  3400 *--------------------------------
  3410        >CIRCLE 40,20,19
  3420        >CIRCLE 40,27,4
  3430        >CIRCLE 30,15,3
  3440        >CIRCLE 50,15,3
  3450 *--------------------------------
  3460 .2     LDA $C000
  3470        BPL .2
  3480        STA $C010
  3490 *--------------------------------
  3500        JMP TEXT
  3510 *--------------------------------
  3520 CIRCLE
  3530        STX CX       get center coordinates
  3540        STY CY
  3550        STA Y1       Y = R
  3560 *--- D = 3 - 2*R ----------------
  3570        ASL          2*R
  3580        EOR #$FF     -2*R-1
  3590        ADC #4       3-2*R
  3600        STA D
  3610 *--- X = 0 ----------------------
  3620        LDA #0
  3630        STA X1
  3640 *---equiv. to lines 1050-1090----
  3650 .1     LDX X1
  3660        LDY Y1
  3670        JSR PLOT.FOUR.POINTS
  3680        LDX Y1
  3690        LDY X1
  3700        JSR PLOT.FOUR.POINTS
  3710 *--------------------------------
  3720        LDA D        IF D<=0 THEN GO TO .2
  3730        BMI .2
  3740        BEQ .2
  3750        SEC          D = D + 4*(X-Y) + 10
  3760        LDA X1
  3770        SBC Y1
  3780        ASL
  3790        ASL
  3800        CLC
  3810        ADC #10
  3820        DEC Y1
  3830        BNE .3
  3840 *--------------------------------
  3850 .2     LDA X1       D = D + 4*X + 6
  3860        ASL
  3870        ASL
  3880        ADC #6
  3890 .3     ADC D
  3900        STA D
  3910        INC X1       X = X + 1
  3920        LDA Y1       IF Y <= X THEN GO TO .1
  3930        CMP X1
  3940        BCS .1
  3950        RTS
  3960 *--------------------------------
  3970 PLOT.FOUR.POINTS
  3980        STX DX
  3990        STY DY
  4000        CLC          PLOT CX+DX,CY+DY
  4010        LDA CX
  4020        ADC DX
  4030        TAY
  4040        LDA CY
  4050        ADC DY
  4060        JSR DPLOT
  4070        SEC          PLOT CX+DX,CY-DY
  4080        LDA CY
  4090        SBC DY
  4100        JSR DPLOT
  4110        SEC          PLOT CX-DX,CY+DY
  4120        LDA CX
  4130        SBC DX
  4140        TAY
  4150        CLC
  4160        LDA CY
  4170        ADC DY
  4180        JSR DPLOT
  4190        SEC          PLOT CX-DX,CY-DY
  4200        LDA CY
  4210        SBC DY
  4220        JMP DPLOT
  4230 *--------------------------------
  4240 X1     .BS 1
  4250 Y1     .BS 1
  4260 SX     .BS 1
  4270 SY     .BS 1
  4280 DX     .BS 1
  4290 DY     .BS 1
  4300 D      .BS 1
  4310 CX     .BS 1
  4320 CY     .BS 1
  4330 *--------------------------------
  4340        .LIF

Next I wrote a normal hi-res version. The listing that follows is a stand-alone program, but you could adapt it to work with Applesoft or to incorporate the CIRCLE subroutine in your own program. I used three subroutines in the Applesoft ROM to do the actual plotting, so the Applesoft ROMs have to be switched on for the program to run. Since I ran it from within the DOS 3.3 version of my assembler, I had to put line 1180 at the beginning to turn on the ROM. Line 1430 puts it back to the language card RAM.

The demonstration part of this program starts at line 1170. I used a macro named CIRCLE again, but the definition is slightly different (see lines 1080-1140). Since the X-coordinate can now be from 0 to 279, it will take two bytes to store. Therefore I wrote my macro to first pick up the two bytes of the X-coordinate in X and Y, get the single byte of the Y-coordinate in A, and then call CENTER to store them in some standard variables. Then I pick up the radius in A and call CIRCLE. The demo draws two "faces" and two circles which go off the edge of the screen. The latter two demonstrate the feature I added to detect off-screen points and bypass plotting them.

The Applesoft ROM subroutines I used are HGR, HCOLOR, and HPLOT. HGR turns on the primary hi-res screen and clears it. HCOLOR is inside the HCOLOR= processor, and expects a color value (0...7) in the X-register. HPLOT expects the X-coordinate in the A-register, and the Y-coordinate in the Y- and X-registers. Calling HPLOT is much faster in machine language, because all reference to floating point values is avoided.

I wrote my own caller for HPLOT in lines 2590-2720. It first checks the coordinates to see if they are on the screen. If not, the subroutine returns without trying to plot. If they are on the screen, I save X and Y and call HPLOT. I saved X and Y here so that I could use them again to plot another point with the same X-coordinate.

I also added a tiny bit of error checking to the CIRCLE subroutine. If the radius is larger than 127 line 1560 catches it and rings the bell. I could have handled larger radii, but it would have required more of the arithmetic to be done in 16-bit precision.

The rest of the code in CIRCLE is very similar to the double lo-res version. I had to go to 16-bit precision for the "D" calculations, and that is the main change.

  1000 *SAVE S.HIRES.CIRCLES
  1010        .OP 65C02
  1020 *--------------------------------
  1030 HGR    .EQ $F3E2
  1040 HPLOT  .EQ $F457
  1050 HCOLOR .EQ $F6F0
  1060 MON.BELL .EQ $FBDD
  1070 *--------------------------------
  1080        .MA CIRCLE
  1090        LDA #]2      CY
  1100        LDX #]1      CX-LOW
  1110        LDY /]1      CX-HI
  1120        JSR CENTER
  1130        LDA #]3      R
  1140        JSR CIRCLE
  1150        .EM
  1160 *--------------------------------
  1170 TC
  1180        LDA $C081    SELECT APPLESOFT ROMS
  1190        JSR HGR      Turn on HI-RES
  1200        LDX #3       Set Color = White
  1210        JSR HCOLOR
  1220 *--------------------------------
  1230        >CIRCLE 40,20,19
  1240        >CIRCLE 40,27,4
  1250        >CIRCLE 30,15,3
  1260        >CIRCLE 50,15,3
  1270 *--------------------------------
  1280        >CIRCLE 140,40,39
  1290        >CIRCLE 140,47,8
  1300        >CIRCLE 130,35,3
  1310        >CIRCLE 150,35,3
  1320 *--------------------------------
  1330        >CIRCLE 140,60,80
  1340        >CIRCLE 260,60,30
  1350 *--------------------------------
  1360 .2     LDA $C000
  1370        BPL .2
  1380        STA $C010
  1390 *--------------------------------
  1400        STA $C051    TEXT
  1410        STA $C05F    SINGLE
  1420        STA $C054
  1430        STA $C080    BACK TO S-C MACRO IN RAM
  1440        RTS
  1450 *--------------------------------
  1460 CENTER
  1470        STA CY
  1480        STX CX
  1490        STY CX+1
  1500        RTS
  1510 *--------------------------------
  1520 BEEP   JMP MON.BELL
  1530 CIRCLE
  1540        STA Y1       Y1 = R
  1550        ASL          2*R
  1560        BCS BEEP     ...RADIUS TOO LARGE
  1570        STA D        D = 3 - 2*R
  1580        SEC
  1590        LDA #3
  1600        SBC D
  1610        STA D
  1620        LDA #0
  1630        STA X1       X1 = 0
  1640        SBC #0
  1650        STA D+1
  1660 *--------------------------------
  1670 .1     LDX X1
  1680        LDY Y1
  1690        JSR PLOT.FOUR.POINTS
  1700        LDX Y1
  1710        LDY X1
  1720        JSR PLOT.FOUR.POINTS
  1730 *--------------------------------
  1740        LDA D+1      IF D <= 0 THEN GO TO .2
  1750        BMI .2
  1760        ORA D
  1770        BEQ .2
  1780 *--------------------------------
  1790        SEC
  1800        LDA Y1
  1810        SBC X1
  1820        JSR TIMES.FOUR
  1830        SEC          10 - 4*(Y-X)
  1840        LDA #10
  1850        SBC TEMP
  1860        STA TEMP
  1870        LDA #0
  1880        SBC TEMP+1
  1890        STA TEMP+1
  1900        DEC Y1
  1910        BNE .3       ...ALWAYS
  1920 *--------------------------------
  1930 .2     LDA X1       6 + 4*X
  1940        JSR TIMES.FOUR
  1950        CLC
  1960        LDA TEMP
  1970        ADC #6
  1980        STA TEMP
  1990        LDA TEMP+1
  2000        ADC #0
  2010 *--------------------------------
  2020 .3     STA TEMP+1
  2030        CLC          D = D + TEMP
  2040        LDA TEMP
  2050        ADC D
  2060        STA D
  2070        LDA TEMP+1
  2080        ADC D+1
  2090        STA D+1
  2100        INC X1
  2110        LDA Y1
  2120        CMP X1
  2130        BCS .1
  2140 .99    RTS
  2150 *--------------------------------
  2160 TIMES.FOUR
  2170        LDY #0
  2180        STY TEMP+1
  2190        ASL
  2200        ROL TEMP+1
  2210        ASL
  2220        ROL TEMP+1
  2230        STA TEMP
  2240        RTS
  2250 *--------------------------------
  2260 PLOT.FOUR.POINTS
  2270        STX DX
  2280        STY DY
  2290        CLC          CX+DX,CY+DY
  2300        LDA CX
  2310        ADC DX
  2320        TAX
  2330        LDA CX+1
  2340        ADC #0
  2350        TAY
  2360        LDA CY
  2370        ADC DY
  2380        JSR CALL.HPLOT
  2390        SEC          CX+DX,CY-DY
  2400        LDA CY
  2410        SBC DY
  2420        JSR CALL.HPLOT
  2430        SEC          CX-DX,CY+DY
  2440        LDA CX
  2450        SBC DX
  2460        TAX
  2470        LDA CX+1
  2480        SBC #0
  2490        TAY
  2500        CLC
  2510        LDA CY
  2520        ADC DY
  2530        JSR CALL.HPLOT
  2540        SEC          CX-DX,CY-DY
  2550        LDA CY
  2560        SBC DY
  2570 ***    JMP CALL.HPLOT
  2580 *--------------------------------
  2590 CALL.HPLOT
  2600        CMP #192
  2610        BCS .2       OFF THE SCREEN
  2620        CPY /280
  2630        BCC .1       ON THE SCREEN
  2640        BNE .2       OFF THE SCREEN
  2650        CPX #280
  2660        BCS .2       OFF THE SCREEN
  2670 .1     PHX
  2680        PHY
  2690        JSR HPLOT
  2700        PLY
  2710        PLX
  2720 .2     RTS
  2730 *--------------------------------
  2740 X1     .BS 1
  2750 Y1     .BS 1
  2760 DX     .BS 1
  2770 DY     .BS 1
  2780 D      .BS 2
  2790 CX     .BS 2
  2800 CY     .BS 1
  2810 TEMP   .BS 2
  2820 *--------------------------------
  2830        .LIF

Some IIgs DemosBob Urschel

I thought some of my fellow AAL readers might like these two programs I wrote for my IIgs. Much of the information I needed to write them came from the excellent book by Gary Bond, "Inside the Apple IIgs", from Sybex.

The graphics demo program will display all of the 4096 colors that are available on the Apple IIgs, 256 colors at a time. Pressing any key except ESCAPE will display the next 256 colors. There are 16 pages altogether. Pressing ESCAPE will exit the program.

The little loop in lines 1480-1580 clears the Super Hi-Res picture buffer. Another way which you might think would be faster is to use the MVN instruction with an overlapping move:

       STZ $2000
       LDA ##$7FFE
       LDX ##$2000
       LDY ##$2001
       MVN $E10000,$E10000

However, this takes longer. The MVN takes 7 cycles per byte moved, and we are moving 8191 bytes. The loop I used takes 13 cycles for each of 4096 byte-pairs. That is a savings of about 4096 cycles, but that is not all of the story. MVN is both loading and storing bytes in bank $E1, which is a slow-ram bank. Two cycles out off every seven must run at 1 megahertz instead of 2.8 megahertz. In my loop only two cycles out of every 13 are in slow RAM. I'll let you figure out exactly what this means in microseconds.

Notice above when I wrote the MVN instruction I used 24-bit values to specify the banks. A more intuitive MVN $E1,$E1 will not work. This is because Bob S-C figured the natural thing to do would be to use the actual label names for the areas being moved, and these would be 24-bit addresses. For example:

       SHR.PIC .EQ $E12000
               STZ >SHR.PIC
               LDA ##8190
               LDX ##SHR.PIC
               LDY ##SHR.PIC+1
               MVN SHR.PIC,SHR.PIC

The sound demo program makes use of the IIgs toolbox. The sound wave is generated by the Applesoft program listed below. I BSAVEd the sine wave data after running the Applesoft program. From the S-C Assembler I loaded and assembled the sound demo program, then BLOADed the sine wave data, and then typed "MGO S" to play the sine wave through the Ensoniq chip. Pressing any key stops the tone.

  900 *SAVE SHR.URSCHEL
  1000 *--------------------------------
  1020 *      Super hires 256 color demo
  1040 *      8-6-87 ru
  1060 *
  1080        .op 65816
  1100 *
  1120 scb.buff   .eq      $9d00   Scanline Control Buffer start
  1140 pix.buff   .eq      $2000   Start of pixel buffer
  1160 pal.buff   .eq      $9e00   Palette data
  1180 kbd        .eq      $c000
  1200 kbd.strb   .eq      $c010
  1210 shr.sw     .eq      $c029  super hires switch
  1215 border     .eq      $C034  border color stored here
  1220 *--------------------------------
  1240 s      clc          native mode
  1260        xce
  1280        lda #$c1     turn on super hires
  1300        sta shr.sw
  1320        lda border
  1340        pha          save border color
  1360        and #$f0     set border to black
  1380        sta border
  1400        lda #$e1     super hires in bank $e1
  1420        pha
  1440        plb
  1460        rep #$30     16 bit regs
  1480 * clear shr buffer
  1500        ldx ##$7ffe  clear 32k
  1520 .1     stz pix.buff,x
  1540        dex
  1560        dex
  1580        bpl .1
  1600 *--------------------------------
  1620 *  set up SCB's 
  1640 *  12 lines per SCB  
  1660 *
  1680 setscb lda ##0      start with palette #0
  1700        ldx ##0
  1720 .2     ldy ##6      repeat for 12 display lines (a twofer)
  1740 .1     sta scb.buff,x    index into SCB buffer
  1760        inx          double inx since acc = 2 bytes
  1780        inx
  1800        dey          done yet?
  1820        bne .1       no, else..
  1840        clc
  1860        adc ##$0101  set up SCB for next palette
  1880        cmp ##$1010  16 palettes yet?
  1900        bne .2       no
  1920 *--------------------------------
  1940 *      set up pixel data
  1960 *
  1980 setpix ldx ##0
  2000 .3     lda ##0
  2020 .2     ldy ##5      320 mode/16 per line = 20 bytes
  2040 .1     sta pix.buff,x
  2060        inx
  2080        inx
  2100        dey          done 20 pixels yet?
  2120        bne .1       no, else..
  2140        clc
  2160        adc ##$1111  get next palette number
  2180        cmp ##$1110  16 palette colors yet?
  2200        bne .2       no, else..
  2220        cpx ##$7800  end of display buffer yet?
  2240        bne .3       no, else..
  2260 *--------------------------------
  2280 *      set up 256 colors in palettes
  2300 *
  2320 setcol lda ##0
  2340 .2     ldx ##0      first palette
  2360 .1     sta pal.buff,x    save color
  2380        clc
  2400        adc ##1      inc color value
  2420        inx
  2440        inx
  2460        cpx ##$200   fill 512 byte palette table
  2480        bne .1
  2500        pha          save acc for next 256 colors
  2520        sep #$20     8 bit acc
  2540 .3     lda kbd   
  2560        bpl .3
  2580        sta kbd.strb      clear keyboard strobe
  2600        cmp #$9b     esc?
  2620        beq end
  2640        rep #$20
  2660        pla          get last color+1
  2680        bra .2       display next 256 colors
  2700 *--------------------------------
  2720 end
  2740        sep #$30     back to 8 bit regs
  2760        pla          clean up stack
  2780        pla
  2800        lda #0
  2820        pha
  2840        plb          back to bank $00
  2860        sec          emulation mode
  2880        xce
  2900        lda #$01
  2920        sta shr.sw   turn off super hires
  2940        pla          get back border color
  2960        sta border
  2980        rts
  2990        .listoff
  900 *SAVE SOUND.DEMO.IIGS
  1000 *--------------------------------
  1020 *      Sound Demo     
  1040 *      8-1-87 ru
  1060 *
  1080        .OP 65816
  1100 Toolbox    .eq      $e10000
  1120 *
  1140 S      clc          Native Mode
  1160        xce
  1180        rep #$30     16 bit registers
  1200        pea $3000    GCB'S (Used by Toolbox: 256 bytes long)
  1220        ldx ##$0208  SoundStartup Tool
  1240        jsl Toolbox
  1260        pea $0001    push the generator number and $01   
  1280        pea $0000    Push location of param table:
  1300        pea $0300    4 bytes - z,b,h,l
  1320        ldx ##$0e08  StartSound tool call
  1340        jsl Toolbox
  1360        sep #$20     set a reg to 8 bits
  1380 .1     lda $c000    Wait for keypress
  1400        bpl .1
  1420        lda $c010    Reset keyboard strobe
  1440        rep #$20     set a reg to 16 bits
  1460        pea $ff7f    push the mask to stop all generators
  1480        ldx ##$0f08  StopSound tool
  1500        jsl Toolbox
  1520        ldx ##$0308  SoundShutdown tool
  1540        jsl Toolbox
  1560        sec
  1580        xce          back to emulation mode
  1600        sep #$30
  1620        rts
  1640 *--------------------------------
  1660 *      parameter table
  1680        .or $300
  1700        .hs 00.20.00.00   Wave Table addr in main ram: l,h,b,z
  1720        .hs 04.00         wave table is four pages long
  1740        .hs 00.0A         frequency: l,h   
  1760        .hs 00.00         Wave Table addr in dedicated ram: l,h
  1780        .hs 02            buffer size in dedicated ram: 256*2^value
  1800        .hs 00            always $00
  1820        .hs 00.03.00.00   next parameter block: l,h,b,z
  1840        .hs ff            volume level
  1860        .listoff
     1000  REM 
               SINE WAVE GENERATOR
              4 CYCL
           ES X 256 BYTES/CYCLE
               1024 BYTES TOTAL

     1010 A = 8192
     1020 R = (2 * 3.14159) / 360
     1030  FOR J = 1 TO 4
     1040  FOR I = 0 TO 361 STEP 1.411765
     1050 S =  INT ( SIN (R * I) * 128 + 128): IF S = 0 THEN S = 1
     1060  POKE A,S: PRINT S,A:A = A + 1
     1070  NEXT : NEXT 

Warning about 65816 JMP IndirectBob Sander-Cederlof

I discovered it the hard way: JMP (addr) and JML (addr) do not act quite like I expected them to.

In these two instructions the assembled address is a 16-bit value, telling the processor where to look to find the address you want to jump to. In the first form, JMP (addr), the effective jump address will be a 16-bit value, so the next instruction will be executed within the same bank as the JMP instruction. In the second form, JML (addr), the effective jump address will be a 24-bit value, specifying the new bank as well as the position in the bank.

But which bank does the processor look in to find the indirect address? There are three possibilities: it could look in the bank specified by the Data Bank Register, the bank specified by the Program Bank Register, or it could always look in Bank $00.

I ran into this after successfully using the JMP (addr,X) and JSR (addr,X) forms, in which the processor looks for an address table in the bank specified by the Program Bank Register. This is natural, because the table of addresses being accessed most likely is in the same bank as the JSR or JMP. It is only slightly restrictive, in that it requires me to be CERTAIN the table of addresses is in the same bank.

Naturally I assumed the JMP (addr) worked the same way. Naturally my assumption was wrong, and wasted a lot of time. Actually, the processor always looks in bank $00 for the indirect address when you use JMP (addr) or JML (addr). Bank $00? I don't know why. But it is right there in black and white on pages 379 and 383 in the Eyes & Lichty book. Strange.

The only rationale I can think of is that the indirect address might be stored in page zero. Come to think of it, this is a pretty common practice and hence it is probably a pretty good thing the processor works this way. One more thing to remember, though.

Here is a table showing all of the JMP and JSR forms, with the page number from the Eyes & Lichty book, the opcode value, the bank used for the indirect address, and the bank jumped into:

                             indirect  destination
     Eyes   Opcode & Syntax    bank       bank

     379    4C   JMP addr      N/A        PBR
     383    6C   JMP (addr)    $00        PBR
     382    7C   JMP (addr,X)  PBR        PBR
     385    5C   JMP long      n/a       stated
              or JML long
     384    DC   JML (addr)    $00       stated

     379    20   JSR addr      n/a        PBR
     382    FC   JSR (addr,X)  PBR        PBR
     385    22   JSR long      n/a       stated

By the way, I used the syntax JML (addr) for the long absolute-indirect Jump. Other assemblers use the syntax JMP [addr]. I chose the bracketless form because the older Apples have no left-bracket on the keyboard.

The form JMP (addr) is used in some existing programs written for the //e and older machines, referencing addresses which are within the body of the program. One such example is inside the code of BASIC.SYSTEM, where it stores the address of the code to process a command in a variable (not in page zero), and then JMPs indirect. Programs which do things like this will not run correctly if they are relocated to higher banks in a blind fashion, by merely setting the PBR and DBR to the new bank and expecting it to run. As I said, I learned the hard way.

You can make it work by setting X=0 and using the JMP (addr,X) form.

I mentioned using the JSR and JMP (addr,X) forms. These are very useful when you have a command processor that needs to branch or call according to a command index. We used to have to use a method which pushed an address from a table on the stack and then did an RTS. For example, a JSR COMMAND.DISPATCHER could call a command processor like this:

     COMMAND.DISPATCHER
            LDA command.number
            ASL             double it
            TAX
            LDA command.table+1,X   high byte
            PHA
            LDA command.table,X     low byte
            PHA
            RTS     "Jump" to the command routine
     command.table
            .DA cmd.0-1,cmd.1-1,cmd.2-1
            .DA cmd.3-1,cmd.4-1,cmd.5-1

Now we can do it an easier way. For example, the code segment:

       LDA command.number
       ASL             double it
       TAX
       JSR (command.table,X)

can call any of a series of subroutines whose addresses are in a list like this:

       command.table
               .DA cmd.0,cmd.1,cmd.2
               .DA cmd.3,cmd.4,cmd.5

Eight QueensPhil Goetz

"Eight Queens" is a classic chess puzzle. The Eight Queens problem is, how many ways can you put eight queens on a chessboard so that no queen can capture another? Obviously, each queen will have to be in a different row. Still, there are 8^8 = 16,777,216 ways to put eight queens on a board with each one in a different row. This is clearly a computation-intensive problem.

If you were to try to solve this problem in LISP on an 8-Megabyte VAX system (as AI programmers have a nasty tendency to do), you would end up with a recursive routine which might give you an answer the same day. I was curious how fast an Apple II can solve it, especially since there are 8 positions in each row of a chessboard, and 8 bits in a byte....

I wrote a brute-force routine. My chessboard is a 8*9 array. At all times, exactly one of the 9 positions in each of the 8 rows has a queen. The rightmost (9th) position in each row (held by the carry) is a placeholder which does not count toward a solution. It works like this:

        Put all queens in the 9th position.
        X=1
Queen:  Rotate the queen in row X left.
        If the queen was rotated from the leftmost
            position back into the 9th, then:

Backtrack:      X=X-1
                If X=0 then end.
                Go to Queen.

        If the queen in row X is in the same column
            or diagonal as another, go to Queen.
        If X=8:
               Print this solution.
               Go to Backtrack.
        X=X+1
        Go to Queen.

As written, QUEENS takes 19 seconds to display all 92 solutions, and just 1.9 seconds to find them without displaying. The mathematically minded may say, "But 92 is not a multiple of 8!" Since a chessboard can be flipped and rotated to get 8 symmetries, you expect a multiple of 8 solutions. But one of the solutions is the same when rotated 180 degrees, thus it provides only 4 symmetrical solutions. There are 12 unique solutions in all.

My display routine, in lines 1620 through the end, works best in 40-column mode. It displays what really looks like a chess board, using inverse blank or inverse Q for one color and normal blank or Q for the other color.

Bob S-C wrote an alternate display routine, shown after my listing as lines 1900 and following, which displays the solutions in numeric form. This is considerable faster, and all 92 solutions will fit on one 80-column screen. In Bob's notation, one digit is displayed for each row of the chess board. The digit shows the position of the queen on that row, with 0 being the leftmost square and 7 being the rightmost square. Bob used conditional assembly to control which display routine is assembled. When line 1000 says "GOETZ .EQ 1" my routine is assembled; when it says "GOETZ .EQ 0" Bob's routine is assembled.

  1000 *SAVE S.EIGHT QUEENS
  1010 *--------------------------------
  1020 BOARD      .EQ $10 thru $17
  1030 MASK       .EQ $18
  1040 XSAV       .EQ $19
  1050 COUNTER    .EQ $1A
  1060 *--------------------------------
  1070 MON.CROUT  .EQ $FD8E
  1080 MON.COUT   .EQ $FDED
  1090 *--------------------------------
  1100 QUEENS
  1110        LDX #7       CLEAR THE CHESS BOARD
  1120        LDA #0
  1130 .0     STA BOARD,X
  1140        DEX
  1150        BPL .0
  1160 * X=FF
  1170 .1     INX          NEW ROW
  1180        CPX #8
  1190        BEQ .9       FINISHED
  1200        SEC          INTRODUCE 1 QUEEN INTO ROW
  1210 .2     ROL BOARD,X
  1220        BCS .8       THIS ROW FAILED, BACKTRACK
  1230        TXA
  1240        BEQ .1       ALWAYS SUCCEEDS WI 1ST ROW
  1250        STX XSAV
  1260        LDA BOARD,X
  1270        STA MASK
  1280 .3     EOR BOARD-1,X    WRAP AROUND TO 0-6
  1290        DEX
  1300        BNE .3
  1310        AND MASK
  1320 * WON'T HAVE MORE THAN 2 QUEENS IN 1 COLUMN
  1330        BEQ .7       FAIL
  1340        LDA #$A      ASL
  1350 .4     STA .5
  1360        LDX XSAV
  1370        LDA MASK
  1380 .5     ASL          CHECK DIAGONAL
  1390        BCS .6       DIAGONAL RAN OFF EDGE
  1400        EOR BOARD-1,X
  1410        BEQ .7       FAIL
  1420        EOR BOARD-1,X    CHANGE BACK TO SHIFTED 8
  1430        DEX
  1440        BNE .5
  1450 .6     LDA #$4A     LSR
  1460        CMP .5
  1470        BNE .4       GO BACK & CHECK OTHER DIAGONAL
  1480        LDX XSAV
  1490        BNE .1       ALWAYS
  1500 .7     LDX XSAV
  1510        INX
  1520 .8     CLC
  1530        DEX          BACKTRACK
  1540        BPL .2       STILL A CHANCE
  1550        RTS          NO MORE SOLUTIONS
  1560 * PRINT BOARD & GO BACK FOR NEXT ONE
  1570 .9     LDX #0
  1580 .10    LDA BOARD,X
  1590        LDY #8
  1600        STY COUNTER
  1610 .11    PHA
  1620        CLC
  1630        TXA
  1640        ADC COUNTER  A=ROW(0-7) + (8-COLUMN(0-7))
  1650        LSR          LOW BIT -> C
  1660        LDA #$7F
  1670        BCC .12
  1680        LDA #$FF     BIT 6 WILL = BIT 7
  1690 .12    ROR          C -> HI BIT
  1700        STA MASK
  1710        PLA
  1720        LDY #$A0     SPACE
  1730        ASL
  1740        BCC .13
  1750        LDY #$D1     Q
  1760 .13    PHA
  1770        TYA
  1780        AND MASK
  1790        JSR MON.COUT
  1800        PLA
  1810        DEC COUNTER
  1820        BNE .11
  1830        JSR MON.CROUT    NEXT ROW
  1840        INX
  1850        CPX #8
  1860        BNE .10
  1870        JSR MON.CROUT    SPACE BETWEEN BOARDS
  1880        JMP .8       WILL GO BACK TO .2
  1890 *--------------------------------
  1000 GOETZ  .EQ 1
  1010 *SAVE S.EIGHT QUEENS.RBSC
  1020 *--------------------------------
  1030 BOARD      .EQ $10 thru $17
  1040 *--------------------------------
  1050 MON.INVFLG .EQ $32
  1060 MON.CROUT  .EQ $FD8E
  1070 MON.COUT   .EQ $FDED
  1080 *--------------------------------
  1090 QUEENS
  1100        LDX #7
  1110        LDA #0
  1120 .0     STA BOARD,X
  1130        DEX
  1140        BPL .0
  1150 *---Next row down----------------
  1160 .1     INX          NEW ROW
  1170        CPX #8
  1180        BEQ .9       ...Finished, have a solution
  1190        SEC          INTRODUCE 1 QUEEN INTO ROW
  1200 *---Next position in row---------
  1210 .2     ROL BOARD,X
  1220        BCS .8       THIS ROW FAILED, BACKTRACK
  1230        TXA
  1240        BEQ .1       ...First row, any position okay
  1250 *---Test if any in same column---
  1260        TAY          START WITH CURRENT ROW
  1270        LDA BOARD,Y
  1280 .3     CMP BOARD-1,Y
  1290        BEQ .7       ...Same column
  1300        DEY
  1310        BNE .3
  1320 *---Test if any in same /--------
  1330        TXA          START WITH CURRENT ROW
  1340        TAY
  1350        LDA BOARD,Y
  1360 .4     LSR          CHECK "/" DIAGONAL
  1370        BCS .5       DIAGONAL RAN OFF EDGE
  1380        CMP BOARD-1,Y
  1390        BEQ .7       ...ON SAME DIAGONAL
  1400        DEY
  1410        BNE .4
  1420 *---Test if any in same \--------
  1430 .5     TXA          START WITH CURRENT ROW
  1440        TAY
  1450        LDA BOARD,Y
  1460 .6     ASL          CHECK "\" DIAGONAL
  1470        BCS .1       ...Diagonal ran off edge
  1480        CMP BOARD-1,Y
  1490        BEQ .7       ...ON SAME DIAGONAL
  1500        DEY
  1510        BNE .6
  1520 *---This position looks good-----
  1530        BEQ .1       ALWAYS
  1540 *---This position failed---------
  1550 .7     CLC
  1560        BCC .2       ...Always
  1570 *---Backtrack--------------------
  1580 .8     CLC
  1590        DEX          BACKTRACK
  1600        BPL .2       STILL A CHANCE
  1610        RTS          NO MORE SOLUTIONS
  1620 *---Print the solution-----------
  1630    .DO GOETZ
  1640 .9     JSR MON.CROUT
  1650        LDX #0
  1660 .10    LDA BOARD,X
  1670        PHA
  1680        LDY #8
  1690 .11    LDA MON.INVFLG
  1700        EOR #$C0
  1710        STA MON.INVFLG
  1720        PLA
  1730        ASL
  1740        PHA
  1750        LDA #" "
  1760        BCC .12
  1770        LDA #"Q"
  1780 .12    JSR MON.COUT
  1790        DEY
  1800        BNE .11
  1810        PLA
  1820        LDA MON.INVFLG
  1830        EOR #$C0
  1840        STA MON.INVFLG
  1850        JSR MON.CROUT    NEXT ROW
  1860        INX
  1870        CPX #8
  1880        BCC .10
  1890   .ELSE
  1900 .9     LDX #0
  1910 .10    LDA BOARD,X
  1920        LDY #0
  1930 .11    ASL
  1940        BCS .12
  1950        INY
  1960        BNE .11
  1970 .12    TYA
  1980        ORA #"0"
  1990        JSR MON.COUT
  2000        INX
  2010        CPX #8
  2020        BCC .10
  2030        LDA #" "
  2040        JSR MON.COUT
  2050        JSR MON.COUT
  2060   .FIN
  2070        JMP .8       Will CLC, set X=7, go to .2
  2080 *--------------------------------

Nifty Sonic SignalsBob Sander-Cederlof

Some years ago I wrote version 2 of the PromGramer software for SCRG. One of the new features I added, at the request of Phil's wife, was a pair of termination tunes. If an EPROM successfully programs, the program twiddles Apple's speaker just right to make a cheerful four-note fanfare. Failure, on the other hand, sounds a six-note SS siren.

I call the two tunes NICE and NASTY, and I thought you might like them for your own programs. If not, the same driver can be used to make other tunes. You can play the NICE tune by calling NICE, or NASTY by calling NASTY.

The tunes are encoded in lines 1280-1320. Each note takes two bytes, the first specifying the length of a half-cycle and the second specifying the number of half-cycles. In other words, pitch and duration. I arrived at the numbers by counting machine cycles for the loops, figuring in the Apple clock speed and the frequency for middle-A, and calculating a few notes by hand. Not very sophisticated, but it works nicely.

I decided to try writing a different one, using a technique that plays equal length notes. Lines 1600-1730 are the note player. Lines 1750-1820 call on it to play the NICE tune. PLAY.NOTE.A counts down a duration count simultaneously with the pitch count, so that you get the same total duration regardless of the pitch. This method is not original with me, but I don't remember where it came from. (Maybe the original Apple documentation.)

The $C030 Apple speaker may be obsolete beside the IIgs Ensoniq chip, but I still like it. R2D2 was no Caruso, either....

  1000 *--------------------------------
  1010 *SAVE S.SIGNAL.TUNES
  1020 *--------------------------------
  1030 T1     .EQ $00
  1040 T2     .EQ $01
  1050 *--------------------------------
  1060 NICE   LDY #TUNE.NICE
  1070        .HS 2C
  1080 NASTY  LDY #TUNE.NASTY
  1090 PLAY.TUNE
  1100 .1     LDA TUNES,Y
  1110        BEQ .4
  1120        STA T1
  1130        LDA TUNES+1,Y
  1140        STA T2
  1150 *---PLAY THE NOTE----------------
  1160 .2     LDA $C030
  1170        LDX T1
  1180 .3     DEX
  1190        BNE .3
  1200        DEC T2
  1210        BNE .2
  1220 *---NEXT NOTE--------------------
  1230        INY
  1240        INY
  1250        BNE .1       ...ALWAYS
  1260 .4     RTS
  1270 *--------------------------------
  1280 TUNES
  1290 TUNE.NICE  .EQ *-TUNES
  1300        .HS BB.8A..94.AD..BB.8A..7C.CE..00
  1310 TUNE.NASTY .EQ *-TUNES
  1320        .HS 94.AD..BB.8A..94.AD..BB.8A..94.AD..BB.8A..00
  1330 TUNE.LO    .EQ *-TUNES
  1340        .HS BB.8A..00
  1350 TUNE.HI    .EQ *-TUNES
  1360        .HS 94.AD..00
  1370 *--------------------------------
  1380 T
  1390 .1     LDA $C000
  1400        BPL .1
  1410        STA $C010
  1420        EOR #$B0
  1430        CMP #8
  1440        BCC .2
  1450        RTS
  1460 .2     SEC          00000ABC 1
  1470        ROR          100000AB C
  1480        ROR          C100000A B
  1490        ROR          BC100000 A
  1500 .3     PHA
  1510        LDY #TUNE.LO
  1520        BCC .4       ...LOW
  1530        LDY #TUNE.HI
  1540 .4     JSR PLAY.TUNE
  1550        PLA
  1560        ASL          B C1000000, C 1000000, 1 0000000
  1570        BNE .3       DO B OR C
  1580        JMP .1       FINISHED
  1590 *--------------------------------
  1600 PLAY.NOTE.A
  1610        TAX
  1620        LDA /12000
  1630        SEC
  1640        STX T1
  1650 .1     DEX
  1660        BNE .3
  1670 .2     LDX T1
  1680        BIT $C030
  1690 .3     DEY
  1700        BNE .1
  1710        SBC #1
  1720        BCS .1
  1730        RTS
  1740 *--------------------------------
  1750 M.NICE LDA #$5D
  1760        JSR PLAY.NOTE.A
  1770        LDA #$4A
  1780        JSR PLAY.NOTE.A
  1790        LDA #$5D
  1800        JSR PLAY.NOTE.A
  1810        LDA #$3E
  1820        JMP PLAY.NOTE.A
  1830 *--------------------------------
  1840 M
  1850        LDA #20
  1860 .1     PHA
  1870        BIT $C000
  1880        BMI .2
  1890        JSR PLAY.NOTE.A
  1900        PLA
  1910        CLC
  1920        ADC #1
  1930        BNE .1
  1940        RTS
  1950 .2     STA $C010
  1960        PLA
  1970        RTS
  1980 *--------------------------------
  9999   .LIF

A New BASIC for the IIgsBob Sander-Cederlof

Apple has announced their new BASIC interpreter for the IIgs. No, it is not an upgraded Applesoft. It is a totally different version, appearing to me to be based on the old Apple /// Business Basic. GSBASIC runs under ProDOS-16, and supports all of the IIgs tools and features.

Features include 9- or 15-digit precision in floating point with exponent range from -308 to +308, plus short and long integers (sounds like SANE); PRINT USING; variable names up to 30 characters long; use of labels rather than line numbers for GOTO and GOSUB; editing features including search/replace; built-in disk file I/O commands; direct statements for access to the various IIgs Tools; and, you guessed it, more! The scheme for linking to assembly language code is the same as in Apple /// Business Basic, via INVOKE, EXFN, and PERFORM statements.

Negatives include the new tradition of extremely long booting time; total in-compatibility with Applesoft programs; requirement for a minimum (MINIMUM!) of 512K RAM; will not work under DOS, ProDOS, or any machine other than a IIgs. It turns out trying to use GSBASIC with less than 1024K is not really reasonable.

The pre-release disk includes ProDOS-16 version 1.3 with the FINDER, GSBASIC, and a sample program which displays four Super Hi-Res pictures under mouse control.

Some interesting trivia: instead of CATALOG and CAT, we now have CATALOG and DIR. Both display an 80-column list of files in the current directory. CATALOG looks a lot like our old ProDOS-8 favorite, and DIR is just a slight revision of it. DIR displays a tiny icon in front of each filename, leaves out the creation date, rounds up the file size to the nearest Kbytes, and spells out the access bits.

If you hit Ctrl-RESET, you are in for a surprise. You get the marvelous message "CANNOT RESET -- $0602", a big beep, and the see-sawing Apple. If you reset again you end up in the monitor. No problem, just boot again, wait five minutes for it all to reload, and then type in your whole program over again!

GSBASIC is available now in pre-release form (beta version 1.0B4) from APDA (Apple Programmer's Development Association), for $50. This is a very low price for such a large system. Applesoft originally cost $100, but of course it came on a ROM card. Applesoft is only 12K bytes long. GSBASIC is currently about 59K bytes long, and growing.


Apple Assembly Line (ISSN 0889-4302) 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.)