Volume 7 -- Issue 12 | September 1987

In This Issue...

- Draw Circles the Fast Way
- Some IIgs Demos
- Warning about 65816 JMP Indirect
- Eight Queens
- Nifty Sonic Signals
- A New BASIC for the IIgs

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 Way | Bob 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 Demos | Bob 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 Indirect | Bob 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 Queens | Phil 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 Signals | Bob 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 IIgs | Bob 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.)