Volume 8 -- Issue 8 | May 1988

In This Issue...

- About S-C Macro Cross Assemblers
- Peeking Inside AppleWorks 1.3, Part 6
- Klaxon Sound Effect
- AppleWorks Segment Functions
- More on AuxTypes in ProDOS CATALOGs
- New Version 1.2 of BASIC.SYSTEM
- The Apple IIx Wish-O-Gram

The Last Issue

With deep regret I have to inform you that this is the last issue of Apple Assembly Line. The income at S-C Software has suddenly and finally decreased beyond the point at which AAL can continue to be published. I have found employment elsewhere, and for the time being have put S-C Software to sleep. I will be working full time now as a programmer for a certain major manufacturer of Apple peripheral boards, for whom I have written a considerable amount of firmware over the last five years: Applied Engineering.

If your subscription expiration date is still in the future, then I owe you something in place of those future issues of the newsletter. I would like to repay you with materials I have on hand, such as back issues of the newsletter, copies of my software products, or perhaps books.

In order to determine how many months remain on your subscription, look at the mailing label. At the right end of the top line you will see a four-digit number, such as 8812. The first two digits are the year, the last two digits are the month of what should have been your last issue. The issue in your hands is issue 8805. Subtract 88 from the year of your expiration date, and multiply the remainder by 12; add the product to the month of your expiration date, and subtract 5; the result should be the number of issues I owe you. For example, if your expiration code is 8903, I owe you 10 more issues.

If possible, I would like to give you back issues in place of future ones. Please write me and let me know which issues you would like. Include some second choices in case I run out of some of the issues. If you had a subscription which included monthly disks, I will also include the disks with the back issues.

Of course, if you already have all of the back issues you will want to work out some other arrangement. Alternatively, you may want to select some item(s) from among the following software and hardware products and apply your remaining subscription toward the purchase price. The actual amount of your credit depends on how much you paid for your subscription; I'll trust you to work that out.

By the time you are reading this, I will be working during the day for my new employer. Please write with your request, or call and leave complete details on my answering machine at (214) 324-2050, by September 30, 1988.

[ The following advertisement is for historical interest only!!! The company closed its doors in 1988.]

A D V E R T I S E M E N T
    S-C Macro Assembler Version 2.0   .  .  .  .  .  .  . DOS $100, ProDOS $100
                                                           .  .   both for $120
    Version 2.0 DOS Upgrade Kit for 1.0/1.1/1.2 owners  .  .  .  .  .  .  . $20
    ProDOS Upgrade Kit for Version 2.0 DOS owners .  .  .  .  .  .  .  .  . $30

    Cross Assemblers for owners of S-C Macro Assembler  .  . $32.50 to $50 each
         (More info on these below)

    S-C DisAssembler (ProDOS only) .  .  .  .  .  .     without source code $30
                                                           with source code $50

    ProVIEW (ProDOS-based disk utility program)   .  .  .  .  .  .  .  .  . $20

    Full Screen Editor for S-C Macro (with complete source code) .  .  .  . $49

    S-C Cross Reference Utility .  .  .  .  .  .  .  .  without source code $20
                                                        with source code    $50

    S-C Word Processor, both DOS & ProDOS, both 40- & 80-columns,
                                    with complete source code    .  .  .    $50

    DP18 and DPFP, double precision math for Applesoft,
                                      including complete source code.  .  . $50

    S-C Documentor (complete commented source code of Applesoft ROMs)
                                                     .  .  .  .  .  .  .  . $50

    AAL Quarterly Disks   .  .  .  .  .  .  .  .  each $15, or any four for $45

    Vinyl disk pages, 6"x8.5", hold two disks each   .  .  .  .  .    10 for $6 *

    Sider 20 Meg Hard Disk, includes controller & software .  .  .  ($695) $550 +

    65802 Microprocessor, 4 MHz (Western Design Center)    .  .  .  .  .  . $25 *

    quikLoader EPROM System (SCRG) .  .  .  .  .  .  .  .  .  .  .  ($179) $170 *
    PROmGRAMER (SCRG)  .  .  .  .  .  .  .  .  .  .  .  .  .  .  ($149.50) $140 *

    *  These items add $2 for first item, $.75 for each additional item for
       shipping in USA.
    +  Add $10 for shipping in USA.
    Customers outside USA inquire for postage needed.
    Texas residents please add 8% sales tax to all orders.
    << Master Card, VISA, Discover and American Express >>
A D V E R T I S E M E N T

About S-C Macro Cross Assemblers | Bob Sander-Cederlof

Combining the versatile Apple II with the S-C Macro Cross Assemblers provides a cost effective and powerful development system for many different microprocessors.

All of the S-C Macro Assemblers are all identical in operation: only the language assembled is different. Each S-C Macro Assembler is a complete macro assembler with an integrated, co-resident program editor, and operates in any member of the Apple II family having at least 48K RAM and one disk drive (ProDOS versions require 64K RAM). Each is written in 6502 assembly language for execution in Apple II series computers, but assembles standard mnemonics for the target processor into binary object code for that processor. The standard version assembles code for either 6502, normal 65C02, the Rockwell special version of the 65C02, or 65C816 microprocessors. Cross Assemblers are available for a wide variety of microprocessors.

S-C Cross Assemblers are sold as supplements to the standard S-C Macro Assembler. The S-C Macro Assembler, complete with 120-page reference manual, costs $100 for either the DOS 3.3 or ProDOS version, or $120 for both; once you have it, you may add as many Cross Assemblers as you wish at a much lower price. The following S-C Macro Cross Assembler versions are now available:

         Microprocessor                  DOS 3.3  ProDOS  Both

    Motorola:            6800,1,2,8/6301  $50      $50     $70
                         6805             $50      $50     $70
                         6809             $32.50   n/a
                         68HC11           $50      $50     $70
                         68000            $50      n/a

    Mitsubishi:          50740 series     $50      $50     $70

    Intel:               8048 family      $32.50   n/a
                         8051 family      $32.50   n/a
                         8080/8085        $32.50   n/a

    Zilog:               Z-80             $32.50   n/a
                         Z-8              $32.50   n/a

    RCA:                 1802/1805        $32.50   n/a

    DEC:                 LSI-11           $50      n/a

    General Instruments: GI-1650          $50      $50     $70
                         GI-1670          $50      $50     $70

    Sharp:               LH5801           $50      $50     $70

The assembled object code may be directed either to Apple memory or to a DOS 3.3 or ProDOS binary file. If you have an EPROM burner, the object can be burned into EPROMs. (We recommend and sell the SCRG PromGramer, which burns any 24- or 28-pin EPROM from 2716 through 27512. It fits in an Apple slot, and is only $140.) Other options are to download your object code to a target system via a serial port, to download to a ROM-emulator, or to execute direcly out of Apple memory with a co-processor card. Co-processor cards for the Z-80, 6809, and 68000 are available from various manufacturers. .............Bob Sander-Cederlof

Peeking Inside AppleWorks 1.3 | Bob Sander-Cederlof

This seems like a good time to give some sort of index to all of the pieces of AppleWorks I have discussed in the past five issues of AAL. The following table is in order by address within the code.

    1000-1185  JMP vector, etc.            Mar 88, Feb 88
    1186-119D  CALL.FOR.AWPROGRAM.DISK     Mar 88
    119E-122C  LOAD.PROGRAM.SEGMENT.A      Mar 88
    122D-1340  LOAD.SEGMENT.FROM.DISK      Mar 88
    1341-1365  APPEND.STRINGS              Dec 87
    1366-136D  CLEAR.MAIN.WINDOW           this issue
    136E-139C  FLUSH.KEYBUF.CHECKING.ESC   this issue
    139D-13B1  CLR.LINE.X.TO.LINE.Y        this issue
    13B2-13C0  CHECK.KEYBUF                Feb 88
    13C1-14CF  various messages            Mar 88, this issue
    14D0       INVERSE.FLAG                Jan 88
    14D1-153F  DISPLAY.STRING              Jan 88
    1540-1543  FUN.CLR.LINE                Jan 88
    1544-1549  FUN.CLR.CH.TO.EOL           Jan 88
    154A-1551  FUN.HOME                    Jan 88
    1552-1575  FUN.CLR.CH.TO.EOS           Jan 88
    1576-1592  FUN.GOTO.XY                 Jan 88
    1593-1598  FUN.CURSOR.LEFT             Jan 88
    1599-159B  FUN.HANG.UP                 Jan 88
    159C-15A0  more of CURSOR.LEFT         Jan 88
    15A1-15AA  FUN.CURSOR.RIGHT            Jan 88
    15AB-15BB  FUN.CURSOR.UP               Jan 88
    15BC-15C9  FUN.CURSOR.DOWN             Jan 88
    15CA-160A  SCROLL                      Jan 88
    160B-160E  FUN.INVERSE                 Jan 88
    160F-1616  FUN.NORMAL                  Jan 88
    1617-1621  FUN.CORNER.BR               Jan 88
    1622-1628  FUN.CURSOR.BOL              Jan 88
    1629-1633  FUN.CORNER.TL               Jan 88
    1634-1644  FUN.FULL.SCREEN             Jan 88
    1645-165D  FUN.BEEP                    Jan 88
    165E-1715  FUN.SHUFFLE                 Jan 88
    1716-1737  BASE.CALC                   Jan 88
    1738-1778  CLR.CH.TO.EOL               Jan 88
    1779-179C  FUNTBL                      Jan 88
    179D-17D0  CONVERT.A.TO.RJBF.STRING    this issue
    17D1-1814  DIVIDE.P0.BY.P2             this issue
    1815-1817  Another HANG.UP             Jan 88
    1818-1822  BEEP.AND.CLEAR.KEYBUF       this issue
    1823-1836  MOVE.CURSOR.TO.XY           Feb 88
    1837-1841  SHOW.HELP.STRING            this issue
    1842-184F  WARN.IF.FULLDESK            this issue
    1850-186B  SHOW.FULLDESK.WARNING       this issue
    186C-1871  SHOW.COMMAND.ENTRY          this issue
    1872-1879  CALL.ORGANIZER              this issue
    187A-18AC  COPY.SCRN.LINE.TO.0900      Feb 88
    18AD-18DC  GET.x.PARMS                 Dec 87
    18DD-18E3  GET.MENU.TABLE.INDEX        Apr 88
    18E4-18F1  MAKE.MENU.LINE.NORMAL       Apr 88
    18F2-190B  MAKE.MENU.LINE.INVERSE      Apr 88
    190C-191C  RESTORE.ESCAPE.AND.HELP     Apr 88
    191D-1A73  SELECT.MENU.LINE            Apr 88
    1A74-1AFB  REVERSE.A.SCREEN.LINE       Apr 88
    1AFC-1AFF  SET.PRODOS.BITMAP           Mar 88
    1B00-1B0A  CLR.PRODOS.BITMAP           Mar 88
    1B0B-1B2A  DRAW.TOP.AND.BOTTOM.LINES   this issue
    1B2B-1B33  POST.CHANGE.FLAG            this issue
    1B34-1B4D  MULTIPLY.X.BY.Y             this issue
    1B4E-1B83  MULTIPLY.P0.BY.P2           this issue
    1B84-1BAB  MOVE.BLOCK.DOWN             Dec 87
    1BAC-1BDE  MOVE.BLOCK.UP               this issue
    1BDF-1BF0  POP.ESCAPE.ROAD.MAP         this issue
    1BF1-1C13  WAIT.FOR.SPACE.RETURN.OR.ESCAPE  this issue
    1C14-1C20  variables for PRINTER       this issue
    1C21-1D0D  PRINTER.DRIVER              this issue
    1D0E           ???
    1D0F-1D2F  PUSH.ESCAPE.ROAD.MAP        this issue
    1D30-1D34  various variables           Feb 88
    1D35-1D45  AW.KEYIN                    Feb 88
    1D46-1DDA  KEYIN.ANOTHER.CHAR          Feb 88
    1DDB-1E7F  KEYIN.ANALYSIS              Feb 88
    1E80-1E89  MOVE.CURSOR.TO.TCOL.TROW    this issue
    1E8A-1E93  SAVE.GOTO.XY                this issue
    1E94-1EA8  MAP.SCRN.CHARS.TO.INTERNAL  Feb 88
    1EA9-1EB3  POINT.PSTR.AT.0A00          Feb 88
    1EB4-1EBE  MAP.LOWER.TO.UPPER          this issue
    1EBF-1ED8  FILTER.LC.TO.UC             Dec 87
    1ED9-1EF7  COMPARE.STRINGS             Dec 87
    1EF8-1F09  MOVE.STRING                 Dec 87
    1F0A-1F3D  READ.KEYBOARD               Feb 88
    1F3E-1F9F  DISPLAY.AT                  this issue
    1FA0-1FA6  TRUNCATE.TO.79.IF.OVER.80   this issue
    1FA7-1FD0  POLL.KEYBOARD               Dec 87
    1FD1-1FDF  DELAY.TENTHS                Jan 88
    1FE0-1FE8  CLEAR.KEYBUF                Feb 88
    1FE9-1FF4  DISPLAY.TOKEN.X             this issue
    1FF5-2028  DISPLAY.ON.LINE.23          this issue
    2029-2092  DISPLAY.MENU.LINE           Apr 88

As you can see, I am trying to fill in all the gaps this month. There is still more code beyond $2092 in the main section of AppleWorks, running all the way up to $2E84, but I have not finished disassembling all of it yet.

      1000 *SAVE AW.SRC.V8N8
      1010        .LIST MOFF
      1020 *--------------------------------
      1030 RJBF.STRING         .EQ $109D   Mar 88 issue
      1040 LOAD.PROGRAM.SEGMENT.A .EQ $11A1  Mar 88 issue
      1050 CHECK.KEYBUF        .EQ $13B2   Feb 88 issue
      1060 DISPLAY.STRING      .EQ $14D1   Jan 88 issue
      1070 MOVE.CURSOR.TO.XY   .EQ $1823   Feb 88 issue
      1080 GET.4.PARMS         .EQ $18AE   Dec 87 issue
      1090 GET.2.PARMS         .EQ $18B2   Dec 87 issue
      1100 GET.A.PARMS         .EQ $18B4   Dec 87 issue
      1110 MOVE.BLOCK.DOWN     .EQ $1B84   Dec 87 issue
      1120 AW.KEYIN            .EQ $1D35   Feb 88 issue
      1130 POINT.PSTR.AT.0A00  .EQ $1EA9   Feb 88 issue
      1140 MOVE.STRING         .EQ $1EF8   Dec 87 issue
      1150 CLEAR.KEYBUF        .EQ $1FE0   Feb 88 issue
      1160 DISPLAY.STRING.P0   .EQ $2093
      1170 DRAW.BOTTOM.LINE    .EQ $20AE
      1180 REPEAT.CHAR.Y.X.TIMES .EQ $20BE
      1190 ROM.D000            .EQ $C082
      1200 RAM.D000            .EQ $C083
      1210 MEASURE.FREE.MEMORY .EQ $D002
      1220 X.D026              .EQ $D026
      1230 DISPLAY.K.AVAIL     .EQ $D044
      1240 DISPLAY.FUNCTION.AND.ESCAPE.MAP .EQ $D029
      1250 MON.COUT            .EQ $FDED
      1260 *--------------------------------
      1270 MON.CH .EQ $24
      1280 MON.CV .EQ $25
      1290 CSWL   .EQ $36
      1300 CSWH   .EQ $37
      1310 PSTR   .EQ $80,81
      1320 FLAG.FOUND.ESCAPE   .EQ $88
      1330 Z.89   .EQ $89
      1340 *---used by Multiply & Divide----
      1350 M.REG         .EQ $91,92
      1360 MUL.X.FACTOR  .EQ $93
      1370 MUL.Y.FACTOR  .EQ $94
      1380 *--------------------------------
      1390 WINDOW.TOP    .EQ $95    initially 2  (3rd from top)
      1400 WINDOW.BOTTOM .EQ $96    initially 21 (3rd from bottom)
      1410 PNTR          .EQ $98,99
      1420 P0            .EQ $9A
      1430 P1            .EQ $9B
      1440 P2            .EQ $9C
      1450 P3            .EQ $9D
      1460 P4            .EQ $9E
      1470 P5            .EQ $9F
      1480 COUNT         .EQ $A0,A1
      1490 Z.A1          .EQ $A1
      1500 DIVISOR       .EQ $F0,F1
      1510 REMAINDER     .EQ $F2,F3
      1520 *--------------------------------
      1530 STR.A             .EQ $0A00
      1540 FLAG.CURRENT.FILE .EQ $0C6C
      1550 FLAG.FOUND.SPACE  .EQ $0CC6
      1560 ESCAPE.ROAD.MAP   .EQ $0CE8  nine 21-byte entries
      1570 OPEN.PRINTER.FLAG .EQ $0EA8
      1580 TCOL   .EQ $0EAD
      1590 TROW   .EQ $0EAE
      1600 X.0EB2 .EQ $0EB2
      1610 X.0EB3 .EQ $0EB3
      1620 X.0EB4 .EQ $0EB4
      1630 *--------------------------------
      1640 *   Following 164 bytes are copy of first 164 bytes
      1650 *      in SEG.PR file (0F19...0FBD):
      1660 *--------------------------------
      1670 CURRENT.PRINTER.NO .EQ $0F3D    Currently Active Printer # (1-3)
      1680 *--------------------------------
      1690 *   Three 36-byte data areas, one for each printer
      1700 *      1:  $F51-F74
      1710 *      2:  $F75-F98
      1720 *      3:  $F99-FBC
      1730 *--------------------------------
      1740 X.0F61 .EQ $0F61
      1750 X.0F70 .EQ $0F70
      1760 X.0F71 .EQ $0F71
      1770 X.0F73 .EQ $0F73
      1780 *--------------------------------
      1790 FLAG.DONT.ANALYZE.KEY  .EQ $0FC4
      1800 SLOTROM.MAP            .EQ $0FC6 ...FCD  (8 BYTES)
      1810 FLAG.APPLE.2C          .EQ $0FEF  01=Apple //c, else 00.
      1820 HIDE.FULLDESK.WARNING  .EQ $0FF3
      1830 CHAR.FOR.BOTTOM.LINE   .EQ $0FF4
      1840 KBYTES.DESKTOP.LEFT    .EQ $0FF5,FF6
      1850 *--------------------------------
      1860        .ph $1366
      1870 *--------------------------------
      1880 *   CLEAR WINDOW, THEN SET FULL SCREEN
      1890 *--------------------------------
      1900 * (1366) 100C 25E2 2710 2ACA 2D34
      1910 CLEAR.MAIN.WINDOW
      1920        LDX WINDOW.TOP
      1930        LDY WINDOW.BOTTOM
      1940        JSR CLR.LINE.X.TO.LINE.Y
      1950        RTS
      1960 *--------------------------------
      1970 *   Flush buffer, but set flags if <SPC> or <ESC> found
      1980 *--------------------------------
      1990 * (136E) 100F
      2000 FLUSH.KEYBUF.CHECKING.ESCAPE.AND.SPACE
      2010        LDA #0
      2020        STA FLAG.FOUND.ESCAPE
      2030        STA FLAG.FOUND.SPACE
      2040        LDA #1       Signal not to analyze char in KEYIN
      2050        STA FLAG.DONT.ANALYZE.KEY
      2060 .1     JSR CHECK.KEYBUF
      2070        BEQ .3       ...no chars in buffer
      2080        JSR AW.KEYIN
      2090        CMP #$1B     <ESC>?
      2100        BNE .2       ...no
      2110        LDA #1       ...yes, set flag and get another
      2120        STA FLAG.FOUND.ESCAPE
      2130        BNE .1       ...always
      2140 .2     CMP #$20     <SPACE>?
      2150        BNE .1       ...no, get another
      2160        LDA #1       ...yes, set flag and get another
      2170        STA FLAG.FOUND.SPACE
      2180        BNE .1       ...always
      2190 .3     LDA #0       now buffer is empty
      2200        STA FLAG.DONT.ANALYZE.KEY   Restore char-analysis in KEYIN
      2210        RTS          return
      2220 *--------------------------------
      2230 *   Clear screen from line (X) to line (Y), and
      2240 *      set window to full screen.
      2250 *      (X)=top line to clear
      2260 *      (Y)=bottom line to clear
      2270 *--------------------------------
      2280 * (139D) 1012 136A
      2290 CLR.LINE.X.TO.LINE.Y
      2300        STX CLRSTR+4
      2310        LDX #79
      2320        JSR MOVE.CURSOR.TO.XY
      2330        JSR DISPLAY.STRING.P0
      2340        .DA CLRSTR
      2350        RTS
      2360 *--------------------------------
      2370 CLRSTR .DA #6       6 bytes in string
      2380        .HS 0C       Set bottom-right corner of window
      2390        .HS 05.00.00 Go to xx,yy
      2400        .HS 04       Clear inside window
      2410        .HS 0F       Back to a full-scrn window
      2420 *--------------------------------
      2430        .ph $13C1
      2440 *--------------------------------
      2450        .MA MSG      MACRO TO SHORTEN LISTING
      2460        .DA #:1-*-1
      2470        .AS "]1"
      2480 :1
      2490        .EM
      2500        .MA AS       MACRO TO SHORTEN LISTING
      2510        .AS /]1/
      2520        .EM
      2530 *--------------------------------
      2540 MSG..1 >MSG "Place the AppleWorks PROGRAM disk in Drive 1 and press Return.  "
      2550 MSG..2 .DA #MSG..3-*-1
      2560        .HS 81       Open-Apple picture
      2570        >AS "-? for Help"
      2580 MSG..3 .DA #MSG..4-*-1
      2590        >AS "Type entry or use "
      2600        .HS 81       Open-Apple picture
      2610        >AS " commands  "
      2620 MSG..4 >MSG "Press Space Bar to continue  "
      2630 MSG..5 >MSG "Do you really want to do this"
      2640 MSG..6 >MSG "Type number, or use arrows, then press Return  "
      2650 MSG..7 .DA #MSG..X-*-1
      2660        .HS 0A       inverse
      2670        >AS " WARNING.  Desktop is full.  Action not completed. "
      2680        .HS 0B       normal
      2690 MSG..X
      2700 *--------------------------------
      2710        .ph $179D
      2720 *--------------------------------
      2730 * (179D) 1018 2037 25A0 25C5 25D6
      2740 *   Convert (A) to right-justified, blank-filled
      2750 *      decimal string in RJBF.STRING.  Also return
      2760 *      the three digits in A,X,Y.  In both places,
      2770 *      the three digits are in ASCII, with leading
      2780 *      zeroes converted to blanks.
      2790 *--------------------------------
      2800 CONVERT.A.TO.RJBF.STRING
      2810        LDY #'0'     Start with ASCII zero
      2820 .1     CMP #100     Count the hundreds
      2830        BCC .2       ...none left
      2840        SEC          take 100 out
      2850        SBC #100
      2860        INY          and count it
      2870        BNE .1       ...always
      2880 .2     LDX #'0'     Start with ASCII zero for 10's
      2890 .3     CMP #10      Count the tens
      2900        BCC .4       ...none left
      2910        SEC          take 10 out
      2920        SBC #10
      2930        INX          and count it
      2940        BNE .3       ...always
      2950 .4     ORA #'0'     Change units to ASCII
      2960        CPY #'0'     Change leading zero to blank
      2970        BNE .5       ...not a leading zero
      2980        LDY #' '     ...lz, change to blank
      2990        CPX #'0'     Might be another lz, tens digit
      3000        BNE .5       ...not a leading zero
      3010        LDX #' '     ...lz, change tens to blank
      3020 .5     STY RJBF.STRING+1   store the 3 characters
      3030        TAY
      3040        STX RJBF.STRING+2
      3050        STY RJBF.STRING+3
      3060        LDA RJBF.STRING+1    also return in AXY
      3070        RTS
      3080 *--------------------------------
      3090 * (17D1) 101E
      3100 DIVIDE.P0.BY.P2
      3110        JSR GET.4.PARMS
      3120 .1     LDA (P0),Y   Get two arguments via P0-P3
      3130        STA M.REG,Y  Dividend
      3140        LDA (P2),Y
      3150        STA DIVISOR,Y   Divisor
      3160        INY
      3170        CPY #1
      3180        BEQ .1
      3190        LDA DIVISOR
      3200        ORA DIVISOR+1
      3210        BNE .2
      3220        SEC          Division by zero, return .CS.
      3230        BCS .5       ...always
      3240 .2     LDA #$00
      3250        STA REMAINDER
      3260        STA REMAINDER+1
      3270        LDX #$10
      3280 .3     ROL M.REG
      3290        ROL M.REG+1
      3300        ROL REMAINDER
      3310        ROL REMAINDER+1
      3320        SEC
      3330        LDA REMAINDER
      3340        SBC DIVISOR
      3350        TAY
      3360        LDA REMAINDER+1
      3370        SBC DIVISOR+1
      3380        BCC .4
      3390        STY REMAINDER
      3400        STA REMAINDER+1
      3410 .4     DEX
      3420        BNE .3
      3430        ROL M.REG
      3440        ROL M.REG+1
      3450        CLC
      3460 .5     RTS
      3470 *--------------------------------
      3480 * (1815) 101B 1599 1815 2D45
      3490 HANG   JMP HANG
      3500 *--------------------------------
      3510 * (1818) 1021 1986 1A2D 1C0C 26CC
      3520 BEEP.AND.CLEAR.KEYBUF
      3530        LDX #$10     BEEP TOKEN
      3540        JSR DISPLAY.TOKEN.X
      3550        JSR CLEAR.KEYBUF
      3560        LDA #$01
      3570        RTS
      3580 *--------------------------------
      3590        .ph $1837
      3600 *--------------------------------
      3610 * (1837) 1027 201C
      3620 SHOW.HELP.STRING
      3630        JSR MEASURE.FREE.MEMORY
      3640        JSR DISPLAY.AT
      3650        .DA #$42,#$17,MSG..2   "Apple-? for Help"
      3660        RTS
      3670 *--------------------------------
      3680 WARN.IF.FULLDESK
      3690        LDA KBYTES.DESKTOP.LEFT
      3700        ORA KBYTES.DESKTOP.LEFT+1
      3710        BNE .1
      3720        JSR SHOW.FULLDESK.WARNING
      3730        LDA #$00
      3740 .1     RTS
      3750 *--------------------------------
      3760 * (1850) 102D 184A
      3770 SHOW.FULLDESK.WARNING
      3780        LDA HIDE.FULLDESK.WARNING
      3790        BNE .2       Don't display anything
      3800        LDX WINDOW.BOTTOM
      3810        INX
      3820        STX .1       Store line number to print on
      3830        JSR DISPLAY.AT
      3840        .DA #$FF
      3850 .1     .DA #$00,MSG..7  "WARNING"
      3860        JSR WAIT.FOR.SPACE.RETURN.OR.ESCAPE
      3870        LDA CHAR.FOR.BOTTOM.LINE
      3880        JSR DRAW.BOTTOM.LINE
      3890 .2     RTS
      3900 *--------------------------------
      3910 * (186C) 1030
      3920 SHOW.ENTER.COMMAND.MSG
      3930        JSR DISPLAY.ON.LINE.23
      3940        .DA MSG..3   "Type Entry or use Apple-commands"
      3950        RTS
      3960 *--------------------------------
      3970 * (1872) 1033 238F
      3980 CALL.THE.ORGANIZER
      3990        LDX #$F8
      4000        TXS
      4010        LDA #$20
      4020        JSR LOAD.PROGRAM.SEGMENT.A
      4030 *---Even though the above is a JSR, it never returns---
      4040 *---from LOAD.PROGRAM.SEGMENT.A, because it enters-----
      4050 *---the ORGANIZER directly-----------------------------
      4060 *--------------------------------
      4070        .ph $1B0B
      4080 *--------------------------------
      4090 * (1B0B) 1048 2765
      4100 DRAW.TOP.AND.BOTTOM.LINES
      4110        LDX #$03     "HOME" TOKEN
      4120        JSR DISPLAY.TOKEN.X
      4130        JSR X.D026
      4140        JSR DISPLAY.FUNCTION.AND.ESCAPE.MAP
      4150        LDX #$00
      4160        LDY WINDOW.TOP
      4170        DEY
      4180        JSR MOVE.CURSOR.TO.XY
      4190        LDX #$4F
      4200        LDY #'='     PRINT 79 ='s above window
      4210        JSR REPEAT.CHAR.Y.X.TIMES
      4220        LDA #'-'     PRINT 79 -'s below window
      4230        JSR DRAW.BOTTOM.LINE
      4240        RTS
      4250 *--------------------------------
      4260 *   Mark that the current file has been changed.
      4270 *--------------------------------
      4280 * (1B2B) 104B
      4290 POST.CHANGE.FLAG
      4300        LDA FLAG.CURRENT.FILE
      4310        ORA #$02
      4320        STA FLAG.CURRENT.FILE
      4330        RTS
      4340 *--------------------------------
      4350 * (1B34) 104E 1A09 1C35 2538 2550 2575
      4360 MULTIPLY.X.BY.Y
      4370        STX MUL.X.FACTOR
      4380        STY MUL.Y.FACTOR
      4390        LDA #$00
      4400        STA M.REG
      4410        LDX #8       8 bits
      4420 .1     LSR MUL.X.FACTOR
      4430        BCC .2
      4440        CLC
      4450        ADC MUL.Y.FACTOR
      4460 .2     ROR
      4470        ROR M.REG
      4480        DEX
      4490        BNE .1
      4500        STA M.REG+1
      4510        RTS
      4520 *--------------------------------
      4530 * (1B4E) 1051
      4540 MULTIPLY.P0.BY.P2
      4550        JSR GET.4.PARMS
      4560 .1     LDA (P0),Y
      4570        STA P4,Y
      4580        LDA (P2),Y
      4590        STA M.REG,Y
      4600        INY
      4610        CPY #$01
      4620        BEQ .1
      4630        LDA #$00
      4640        STA COUNT
      4650        STA Z.A1
      4660        LDX #$11
      4670        CLC
      4680 .2     ROR Z.A1
      4690        ROR COUNT
      4700        ROR M.REG+1
      4710        ROR M.REG
      4720        BCC .3
      4730        LDA COUNT
      4740        CLC
      4750        ADC P4
      4760        STA COUNT
      4770        LDA Z.A1
      4780        ADC P5
      4790        STA Z.A1
      4800 .3     DEX
      4810        BNE .2
      4820        RTS
      4830 *--------------------------------
      4840        .ph $1BAC
      4850 *--------------------------------
      4860 * (1BAC) 1057 1D1C 2404 263B 2653
      4870 MOVE.BLOCK.UP
      4880        LDA #$06
      4890        JSR GET.A.PARMS
      4900        LDA P5
      4910        BEQ .1
      4920        CLC
      4930        ADC P1
      4940        STA P1
      4950        LDA P5
      4960        ADC P3
      4970        STA P3
      4980 .1     LDY P4
      4990        BEQ .3
      5000 .2     DEY
      5010        LDA (P2),Y
      5020        STA (P0),Y
      5030        TYA
      5040        BNE .2
      5050 .3     DEC P5
      5060        BMI .5
      5070        DEC P1
      5080        DEC P3
      5090 .4     DEY
      5100        LDA (P2),Y
      5110        STA (P0),Y
      5120        TYA
      5130        BNE .4
      5140        BEQ .3
      5150 .5     RTS
      5160 *--------------------------------
      5170 * (1BDF) 105A
      5180 POP.ESCAPE.ROAD.MAP
      5190        JSR MOVE.BLOCK.DOWN
      5200        .DA ESCAPE.ROAD.MAP,ESCAPE.ROAD.MAP+21,168
      5210        LDA #$00     MARK LAST ENTRY EMPTY
      5220        STA ESCAPE.ROAD.MAP+168
      5230        JSR DISPLAY.FUNCTION.AND.ESCAPE.MAP
      5240        RTS
      5250 *--------------------------------
      5260 * (1BF1) 105D 1862 2389 2728 2ADB
      5270 WAIT.FOR.SPACE.RETURN.OR.ESCAPE
      5280        JSR CLEAR.KEYBUF
      5290        JSR DISPLAY.ON.LINE.23
      5300        .DA MSG..4   "Press Space Bar to continue"
      5310        LDA #0
      5320        STA FLAG.FOUND.ESCAPE
      5330 .1     JSR AW.KEYIN
      5340        CMP #$20
      5350        BEQ .3       ...GOT A SPACE
      5360        CMP #$0D
      5370        BEQ .3       ...GOT <RETURN>
      5380        CMP #$1B
      5390        BEQ .2       ...GOT <ESCAPE>
      5400        JSR BEEP.AND.CLEAR.KEYBUF
      5410        BNE .1       ...ALWAYS
      5420 .2     INC FLAG.FOUND.ESCAPE     RETURN FLAG.FOUND.ESCAPE=$01, STATUS .NE.
      5430 .3     RTS
      5440 *--------------------------------
      5450 * (1C14) 1CB3 1CDD
      5460 PD.CHARCNT .BS 1
      5470 * (1C15) 1C3F 1CF1
      5480 PRNTR.CRLF.FLAG .BS 1
      5490 * (1C16) 1C6D 2309 2336
      5500 I.1C16 .BS 1        'e' if //e, or 'c' if //c
      5510 PRNTR.SETUP.STRING .BS 10
      5520 *--------------------------------
      5530 * (1C21) 1060 1E22 1E32 1E39 1E48
      5540 *   Called from KEYIN when Apple-H is pressed,
      5550 *      and from JMP table at $1060
      5560 *   (A) = $00       Open Printer
      5570 *         $FE       Print CRLF
      5580 *         $FF       Close Printer
      5590 *        other      A=#chars, P0,P1 is address of text.
      5600 *--------------------------------
      5610 PRINTER.DRIVER
      5620        LDX #$00
      5630        STX MON.CH
      5640        STX MON.CV
      5650        TAX
      5660        BEQ .1       A=00, Open Printer
      5670        JMP .6       SOME OTHER FUNCTION
      5680 *---Open Printer-----------------
      5690 .1     LDX CURRENT.PRINTER.NO
      5700        BEQ .5       None, or it would have been 1-3
      5710        DEX          change range to 0,1,2
      5720        LDY #36      multiply by 36 bytes per printer
      5730        JSR MULTIPLY.X.BY.Y
      5740        LDX M.REG
      5750        LDA X.0F73,X
      5760        AND #$20     non-zero means print LF after CR
      5770        STA PRNTR.CRLF.FLAG
      5780        LDA X.0F71,X
      5790        TAX
      5800        LDA SLOTROM.MAP,X
      5810        AND #$02
      5820        BEQ .5       Not a printer interface, for sure
      5830        CPX OPEN.PRINTER.FLAG
      5840        BEQ .5
      5850        STX OPEN.PRINTER.FLAG
      5860        TXA
      5870        ORA #$C0
      5880        STA CSWH
      5890        LDA #$00
      5900        STA CSWL
      5910        LDA HANDLE.PRNTR.SETUP.STRING
      5920        STA P0
      5930        LDA HANDLE.PRNTR.SETUP.STRING+1
      5940        STA P1
      5950        LDX M.REG
      5960        LDA X.0F70,X
      5970        CMP I.1C16
      5980        BNE .2
      5990        LDA HANDLE.0F61
      6000        CLC
      6010        ADC M.REG
      6020        STA P0
      6030        LDA HANDLE.0F61+1
      6040        ADC #$00
      6050        STA P1
      6060 .2     LDY #$00
      6070        LDA (P0),Y
      6080        BEQ .5
      6090        STA P2
      6100        STA ROM.D000
      6110 .3     INY
      6120        LDA (P0),Y
      6130        CMP #$09
      6140        BNE .4
      6150        LDA #$89
      6160        LDX FLAG.APPLE.2C
      6170        BEQ .4       ...not an Apple //c
      6180        LDX OPEN.PRINTER.FLAG
      6190        CPX #$02
      6200        BNE .4
      6210        LDA #$01
      6220 .4     JSR MON.COUT
      6230        CPY P2
      6240        BCC .3
      6250 .5     JMP .13
      6260 *--------------------------------
      6270 .6     CMP #$FE
      6280        BEQ .11      A=FE, Print CRLF
      6290        BCS .12      A=FF, Close Printer
      6300        STA PD.CHARCNT    A=number chars to print
      6310        JSR GET.2.PARMS
      6320        LDA OPEN.PRINTER.FLAG
      6330        BEQ .13
      6340        STA ROM.D000
      6350        LDY #$00
      6360 .7     LDA (P0),Y
      6370        CMP #$81     Change "Apple" to "@"
      6380        BNE .8       ...not an apple
      6390        LDA #$40
      6400        BNE .9       ...always
      6410 .8     CMP #$8D     change <RETURN> to <SPACE>
      6420        BNE .9       ...not <RETURN>
      6430        LDA #$20
      6440 .9     CMP #$09     change 09 (ctrl-I) to 89
      6450        BNE .10      ...not 09
      6460        LDA #$89
      6470 .10    JSR MON.COUT      out to the printer, finally
      6480        INY
      6490        CPY PD.CHARCNT
      6500        BCC .7       ...more to print
      6510        BCS .13      ...finished
      6520 *---Print CRLF-------------------
      6530 .11    LDA OPEN.PRINTER.FLAG
      6540        BEQ .13
      6550        STA ROM.D000
      6560        LDA #$0D
      6570        JSR MON.COUT
      6580        LDA PRNTR.CRLF.FLAG
      6590        BEQ .13
      6600        LDA #$0A
      6610        JSR MON.COUT
      6620        JMP .13
      6630 *---Close Printer----------------
      6640 .12    LDA #$00
      6650        STA OPEN.PRINTER.FLAG
      6660 .13    LDA RAM.D000
      6670        LDA RAM.D000
      6680        RTS
      6690 *--------------------------------
      6700 * (1D0A,B) 1C5E 1C63
      6710 HANDLE.PRNTR.SETUP.STRING .DA PRNTR.SETUP.STRING
      6720 * (1D0C,D) 1C72 1C7A
      6730 HANDLE.0F61 .DA X.0F61
      6740 *--------------------------------
      6750 * (1D0E) 1E10
      6760        .BS 1
      6770 *--------------------------------
      6780 * (1D0F) 1063
      6790 PUSH.ESCAPE.ROAD.MAP
      6800        JSR GET.2.PARMS
      6810        LDA P0
      6820        STA .1       FILL IN ADDRESS
      6830        LDA P1
      6840        STA .1+1
      6850        JSR MOVE.BLOCK.UP
      6860        .DA ESCAPE.ROAD.MAP+21,ESCAPE.ROAD.MAP,168
      6870        JSR MOVE.STRING
      6880        .DA ESCAPE.ROAD.MAP
      6890 .1     .DA 0000    FILLED IN
      6900        JSR DISPLAY.FUNCTION.AND.ESCAPE.MAP
      6910        RTS
      6920 *--------------------------------
      6930        .ph $1E80
      6940 *--------------------------------
      6950 * (1E80) 1069 1911 193C 19B2 2025 2612 261A
      6960 MOVE.CURSOR.TO.TCOL.TROW
      6970        LDX TCOL
      6980        LDY TROW
      6990        JSR MOVE.CURSOR.TO.XY
      7000        RTS
      7010 *--------------------------------
      7020 * (1E8A) 106C
      7030 SAVE.GOTO.XY
      7040        STX TCOL
      7050        STY TROW
      7060        JSR MOVE.CURSOR.TO.XY
      7070        RTS
      7080 *--------------------------------
      7090        .ph $1EB4
      7100 *--------------------------------
      7110 * (1EB4) 106F
      7120 MAP.LOWER.TO.UPPER
      7130        CMP #'a'
      7140        BCC .1       ...not lower-case
      7150        CMP #'z'+1
      7160        BCS .1       ...not lower-case
      7170        AND #$DF     flip to upper-case
      7180 .1     RTS
      7190 *--------------------------------
      7200        .ph $1F3E
      7210 *--------------------------------
      7220 *   Display string (P2,P3) at (P0,P1)
      7230 *      JSR DISPLAY.AT
      7240 *      .DA #column,#line
      7250 *      .DA string.address
      7260 *
      7270 *   If column value is negative but not $FF, then add $94
      7280 *      which clears bit 7 and adds 20
      7290 *   If column value is $FF then center the string in 80 columns
      7300 *--------------------------------
      7310 * (1F3E) 107B 183A 185B 200C 25E5 2713 271A 2ACD 2B70 2B77
      7320 * (1F3E) 2B8C 2B93 2BA1 2BA8 2D37 2D3E
      7330 DISPLAY.AT
      7340        JSR GET.4.PARMS
      7350        LDA #$05     Build string to set cursor position
      7360        STA STR.A
      7370        LDA P0
      7380        STA STR.A+1
      7390        LDA P1
      7400        STA STR.A+2
      7410        LDA P2
      7420        CLC
      7430        ADC #1       Build address of 1st char after length
      7440        STA X.0EB2
      7450        LDA P3
      7460        ADC #0
      7470        STA X.0EB3
      7480        LDY #0       Get length of string
      7490        LDA (P2),Y
      7500        JSR TRUNCATE.TO.79.IF.OVER.80
      7510        STA X.0EB4
      7520        LDA STR.A+1   Was P0 positive, meaning absolute column?
      7530        BPL .2       ...yes
      7540        CMP #$FF
      7550        BNE .1       ...not centering, so add $94
      7560        LDA #80      $FF means to center in 80 columns
      7570        SEC          (80-length)/2
      7580        SBC X.0EB4
      7590        LSR
      7600        STA STR.A+1
      7610        JMP .2
      7620 *--------------------------------
      7630 .1     CLC
      7640        ADC #$94
      7650        STA STR.A+1
      7660 .2     JSR POINT.PSTR.AT.0A00
      7670        LDA #3
      7680        JSR DISPLAY.STRING
      7690        LDA X.0EB2
      7700        STA PSTR
      7710        LDA X.0EB3
      7720        STA PSTR+1
      7730        LDA X.0EB4
      7740        BEQ .3       null string
      7750        JSR DISPLAY.STRING
      7760 .3     RTS
      7770 *--------------------------------
      7780 * (1FA0) 1F63 20A7 20C2
      7790 TRUNCATE.TO.79.IF.OVER.80
      7800        CMP #81
      7810        BCC .1
      7820        LDA #79
      7830 .1     RTS
      7840 *--------------------------------
      7850        .ph $1FE9
      7860 *--------------------------------
      7870 * (1FE9) 108A 181A 1970 19B7 19C2 1A1E 1A97 1AAB 1AC3 1AD8
      7880 * (1FE9) 1B0D 2015 2B5F
      7890 DISPLAY.TOKEN.X
      7900        STX STR.A
      7910        JSR POINT.PSTR.AT.0A00
      7920        LDA #1
      7930        JSR DISPLAY.STRING
      7940        RTS
      7950 *--------------------------------
      7960 *   JSR DISPLAY.ON.LINE.23
      7970 *   .DA string
      7980 *
      7990 *   1.  Display string starting at col. 0, line 23
      8000 *   2.  Clear rest of the line
      8010 *   3.  If Z.89 is $00, display "xxxxK Avail.";
      8020 *       otherwise, display "Apple-? for Help"
      8030 *   4.  Move cursor to end of the string.
      8040 *--------------------------------
      8050 * (1FF5) 1093 118D 186C 1931 1A45 1BF4 20D6 25F3
      8060 DISPLAY.ON.LINE.23
      8070        JSR GET.2.PARMS
      8080        LDA P0
      8090        STA .1       store address in parameter below
      8100        LDA P1
      8110        STA .1+1
      8120        LDA (P0),Y   length of string
      8130        STA TCOL     later position cursor to end of string
      8140        LDA #23         on line 23
      8150        STA TROW
      8160        JSR DISPLAY.AT
      8170        .DA #0,#23   Column 0, line 23
      8180 .1     .DA 0000     String address, filled in
      8190        LDX #$01     "Clear to End of Line" token
      8200        JSR DISPLAY.TOKEN.X   Print the token
      8210        LDA Z.89
      8220        BEQ .2       ...display "xxxxK Avail."
      8230        JSR SHOW.HELP.STRING   Display "Apple-? for Help"
      8240        JMP .3
      8250 .2     JSR DISPLAY.K.AVAIL   Display "xxxxK Avail."
      8260 .3     JSR MOVE.CURSOR.TO.TCOL.TROW
      8270        RTS
      8280 *--------------------------------

Klaxon Sound Effect | Robert C. Moore

Here is an interesting little sound effect generator, which you might like to use to call attention to an operator error. It uses the simple Apple speaker, so it is compatible with all of the many models in the Apple II series and even the clones.

Lines 1110-1130 call on the SOUNDS subroutine to generate two bursts of sound. The first burst combines plays a higher note, the second a lower note. Both notes are combined inside SOUNDS with a pitch that is in between the two. The total effect sounds a little like a klaxon to me.

Bob S-C inserted line 1100, which turns the dee-daw sound into dee-daw-dee-daw. You might also enjoy experimenting with different pitches and durations. You can change the intermediate pitch by change the value 63 in lines 1190 and 1240.

You might notice that DURATION2 never gets initialized to anything. If you want to, you could store 0 there by inserting these lines:

           1191    LDA #0
           1192    STA DURATION2

However, you will not be able to tell the difference in how it sounds. The total time the horn blows is DURATION1 times 256, less up to 255 if DURATION2 starts out non-zero. In the worst case, with DURATION2 starting at 1, the horn will finish blowing about 5% sooner.

      1000 *SAVE S.KLAXON
      1010 *--------------------------------
      1020 *   from Robert C. Moore, Laurel, Maryland.
      1030 *--------------------------------
      1040 DURATION1  .EQ 0
      1050 DURATION2  .EQ 1
      1060 PITCH      .EQ 2
      1070 *--------------------------------
      1080 SPEAKER    .EQ $C030
      1090 *--------------------------------
      1100 BOBSC  JSR KLAXON
      1110 KLAXON LDY #50      FIRST PRIMARY PITCH
      1120        JSR SOUNDS
      1130        LDY #80      SECOND PRIMARY PITCH
      1140 *--------------------------------
      1150 SOUNDS
      1160        STY PITCH    SAVE CALLER'S Y-PITCH
      1170        LDA #20      LENGTH OF SOUND
      1180        STA DURATION1
      1190        LDX #63      SECONDARY PITCH
      1200 *--------------------------------
      1210 .2     DEX          COUNT DOWN SECONDARY CYCLE
      1220        BNE .3       ...NOT TIME FOR CLICK YET
      1230        BIT SPEAKER  ...CLICK NOW
      1240        LDX #63      START ANOTHER CYCLE
      1250 *--------------------------------
      1260 .3     DEY          COUNT DOWN PRIMARY CYCLE
      1270        BNE .4       ...NOT TIME FOR CLICK YET
      1280        BIT SPEAKER  ...CLICK NOW
      1290        LDY PITCH    START ANOTHER CYCLE
      1300 *--------------------------------
      1310 .4     DEC DURATION2     256*20 TIMES ALTOGETHER
      1320        BNE .2
      1330        DEC DURATION1
      1340        BNE .2
      1350        RTS
      1360 *--------------------------------
      1370 T      JSR KLAXON.2
      1380 KLAXON.2
      1390        LDY #60      FIRST PRIMARY PITCH
      1400        JSR SOUNDS.2
      1410        LDY #96      SECOND PRIMARY PITCH
      1420 *--------------------------------
      1430 SOUNDS.2
      1440        STY PITCH    SAVE CALLER'S Y-PITCH
      1450        LDX #76      SECONDARY PITCH
      1460        LDA #100     LENGTH OF SOUND
      1470 *--------------------------------
      1480 .1     PHA
      1490 .2     DEX          COUNT DOWN SECONDARY CYCLE
      1500        BNE .3       ...NOT TIME FOR CLICK YET
      1510        BIT SPEAKER  ...CLICK NOW
      1520        LDX #76      START ANOTHER CYCLE
      1530 *--------------------------------
      1540 .3     DEY          COUNT DOWN PRIMARY CYCLE
      1550        BNE .4       ...NOT TIME FOR CLICK YET
      1560        BIT SPEAKER  ...CLICK NOW
      1570        LDY PITCH    START ANOTHER CYCLE
      1580 *--------------------------------
      1590 .4     SBC #1       COUNT DOWN TOTAL TIME
      1600        BNE .2
      1610        PLA
      1620        SBC #1
      1630        BNE .1
      1640        RTS
      1650 *--------------------------------

AppleWorks Segment Functions | Steve Stephenson

I have been disassembling and patching AppleWorks since 1984 for CheckMate Technology, and have learned a few things about it. One interesting task was trying to figure out what each one of the segments in the SEG.M0 and SEG.M1 files does. As near as I can tell, here is the breakdown for AppleWorks 1.3:

    Seg.01 DB Common               Seg.24 SS Common
    Seg.02 DB Main                 Seg.25 SS Main
    Seg.03 DB Help                 Seg.26 SS Help
    Seg.04 DB SingleLayout         Seg.27 SS Print
    Seg.05 DB MultipleLayout       Seg.28 SS Layout
    Seg.06 DB ChangeNames          Seg.29 SS Edit
    Seg.07 DB Search               Seg.30 SS ToClipboard
    Seg.08 DB Sort                 Seg.31 SS Options
    Seg.09 DB Report Main
    Seg.10 DB Report Util          Seg.32 DeskTop Manager
    Seg.11 DB Report New           Seg.33 File Loader
    Seg.12 DB Report Layout        Seg.34 Printer Setups
    Seg.13 DB Report Open          Seg.35 Import DIF for DB
    Seg.14 DB Report Output        Seg.36 File Saver
    Seg.15 -doesn't exist-         Seg.37 Import Quick Files for DB
                                   Seg.38 Import ASCII Text for WP
    Seg.16 WP Common               Seg.39 Import VisiCalc for SS
    Seg.17 WP Main
    Seg.18 WP Help                 Seg.40 Main Help
    Seg.19 WP Print
    Seg.20 -doesn't exist-         Seg.41 Import Text for DB
    Seg.21 -doesn't exist-         Seg.42 Import DIF for SS
    Seg.22 SANE
    Seg.23 SANE                    Seg.43 Disk Formatter

I also wrote a program which will break out the segments from the SEG.M0 and SEG.M1 files into individual binary files, each with their proper SEG number, load address, and length.

There is no fancy prefix handling in the program, so the two source files and all the resultant files must all land in the same directory. I use a RAM disk of at least 600 blocks, for speed. There is also not any fancy error handling. If any error occurs, the hexadecimal error code returned by MLI will be displayed. If not, 00 will be displayed when it's finished.

The monthly AAL disk also includes a slightly different version of the Segment Splitter, which displays a line for each segment including the segment number, the file offset, starting address, and length.

      1000 *SAVE SEG.SPLITTER
      1010        .LIST MOFF
      1020 *--------------------------------
      1030 *  AppleWorks Segment Splitter
      1040 *      by Steve Stephenson
      1050 *--------------------------------
      1060 MLI        .EQ $BF00
      1070 ERRCODE    .EQ $BF0F
      1080 CREATE     .EQ $C0       ProDOS MLI Functions
      1090 OPEN       .EQ $C8
      1100 READ       .EQ $CA
      1110 WRITE      .EQ $CB
      1120 CLOSE      .EQ $CC
      1130 SETMARK    .EQ $CE
      1140 *--------------------------------
      1150        .MA MLI      Function, Parameter List
      1160        JSR MLI
      1170        .DA #]1,]2
      1180        BCC :1       No Error
      1190        JMP ERROR
      1200 :1
      1210        .EM
      1220 *--------------------------------
      1230        .MA STR
      1240        .DA #:1-*-1  Number of bytes in string
      1250        .AS -"]1"    String itself
      1260 :1
      1270        .EM
      1280 *--------------------------------
      1290 BUFFER.INDEX .EQ $300
      1300 FILE.CNT .EQ $6
      1310 *--------------------------------
      1320        .OR $1000
      1330        .TF B.SEG.SPLITTER
      1340 *--------------------------------
      1350 SEGMENT.SPLITTER
      1360        LDA #1
      1370        STA FILE.CNT
      1380 PRELOOP
      1390        >MLI OPEN,P.OPEN.SEGMX    open seg.m0/1
      1400        LDA P.OPEN.SEGMX+5        file refnum
      1410        STA P.READ.INDEX+1
      1420        STA P.READ.SEGNN+1
      1430        STA P.SET.MARK+1
      1440        >MLI READ,P.READ.INDEX     read the index
      1450 *--------------------------------
      1460 MAINLOOP
      1470        LDA FILE.CNT find offset to this seg
      1480        ASL          by multiplying by three
      1490        ADC FILE.CNT
      1500        TAX
      1510        LDA BUFFER.INDEX,X   get starting point in file
      1520        STA P.SET.MARK+2     for SETMARK call
      1530        LDA BUFFER.INDEX+1,X
      1540        STA P.SET.MARK+3
      1550        LDA BUFFER.INDEX+2,X
      1560        STA P.SET.MARK+4
      1570        ORA P.SET.MARK+3     if 000000, no segment exists
      1580        ORA P.SET.MARK+2
      1590        BNE .1               ...there is a segment
      1600        JMP NEXT             ...not one, go to next one
      1610 .1     LDA BUFFER.INDEX+3,X
      1620        ORA BUFFER.INDEX+4,X
      1630        ORA BUFFER.INDEX+5,X
      1640        BNE .2
      1650        JMP NEXT
      1660 *---Compute length of segment----
      1670 .2     SEC
      1680        LDA BUFFER.INDEX+3,X start of next seg
      1690        SBC BUFFER.INDEX,X   - start of this
      1700        STA P.READ.SEGNN+4   = length of this
      1710        STA P.WRIT.SEGNN+4
      1720        LDA BUFFER.INDEX+4,X
      1730        SBC BUFFER.INDEX+1,X
      1740        STA P.READ.SEGNN+5
      1750        STA P.WRIT.SEGNN+5
      1760        ORA P.READ.SEGNN+4   if length = 0000, go to next
      1770        BNE .3
      1780        JMP NEXT
      1790 *---Read the Segment-------------
      1800 .3     >MLI SETMARK,P.SET.MARK  move to the segment
      1810        >MLI READ,P.READ.SEGNN   read it into main BUFFER
      1820 *---Compute Start Address--------
      1830        SEC
      1840        LDA BUFFER         ending addr of this seg
      1850        SBC P.READ.SEGNN+4 - length of this segment
      1860        TAX                = equals starting addr
      1870        LDA BUFFER+1
      1880        SBC P.READ.SEGNN+5
      1890        STA P.CREATE+6
      1900        TXA                round to an even page
      1910        BEQ .4
      1920        INC P.CREATE+6
      1930        LDA #0
      1940 .4     STA P.CREATE+5
      1950 *---Create the Segment File------
      1960        >MLI CREATE,P.CREATE  create an individual seg.xx
      1970        >MLI OPEN,P.OPEN.SEGNN    open a seg.xx
      1980        LDA P.OPEN.SEGNN+5        refnum of file
      1990        STA P.WRIT.SEGNN+1
      2000        STA P.CLOSE+1
      2010        >MLI WRITE,P.WRIT.SEGNN   write out a seg.xx
      2020        >MLI CLOSE,P.CLOSE        close seg.xx
      2030 *--------------------------------
      2040 NEXT
      2050        INC SNUMLO
      2060        LDA SNUMLO
      2070        CMP #"9"+1
      2080        BCC .1
      2090        INC SNUMHI
      2100        LDA #"0"
      2110        STA SNUMLO
      2120 .1     INC FILE.CNT
      2130        LDA FILE.CNT
      2140        CMP #10
      2150        BCC .2
      2160        BEQ .3
      2170        CMP #44
      2180        BCS .4
      2190 .2     JMP MAINLOOP
      2200 .3     INC NAME.M1
      2210        JSR CLOSEALL
      2220        JMP PRELOOP
      2230 .4     JSR CLOSEALL
      2240 *--------------------------------
      2250 ERROR
      2260        LDA ERRCODE
      2270        JSR $FDDA
      2280 *--------------------------------
      2290 CLOSEALL
      2300        LDA #0
      2310        STA P.CLOSE+1
      2320        >MLI CLOSE,P.CLOSE
      2330        RTS
      2340 *--------------------------------
      2350 NAME.MX  >STR "SEG.M0"
      2360 NAME.M1   .EQ *-1
      2370 *--------------------------------
      2380 NAME.NN  >STR "SEG.01"
      2390 SNUMLO    .EQ *-1
      2400 SNUMHI    .EQ *-2
      2410 *--------------------------------
      2420 *   Parameter Lists for MLI Calls
      2430 *--------------------------------
      2440 P.OPEN.SEGMX .DA #3,NAME.MX,BUFFER.SEGMX,#0
      2450 P.READ.INDEX .DA #4,#00,BUFFER.INDEX,140,0000
      2460 P.SET.MARK   .DA #2,#00,<000000
      2470 P.READ.SEGNN .DA #4,#00,BUFFER,0000,0000
      2480 P.CREATE     .DA #7,NAME.NN,#$C3,#$06,0000,#00,0000,0000
      2490 P.OPEN.SEGNN .DA #3,NAME.NN,BUFFER.SEGNN,#00
      2500 P.WRIT.SEGNN .DA #4,#00,BUFFER,0000,0000
      2510 P.CLOSE      .DA #1,#00
      2520 *--------------------------------
      2530              .DUMMY
      2540              .BS *+255/256*256-*   force to page boundary
      2550 BUFFER.SEGMX .BS $400
      2560 BUFFER.SEGNN .BS $400
      2570 BUFFER       .EQ *
      2580              .ED
      2590 *--------------------------------

More on AuxTypes in ProDOS CATALOGs | Bob Sander-Cederlof

Last month I presented a patch for BASIC.SYSTEM and another for SCASM.SYSTEM to cause the AuxType to be displayed for all file types, rather than just for TXT and BIN files. My patch was not quite sufficient, it turns out. My patch only worked for files whose type is a named type, displayed in the catalog with a three-letter name. Files with types displayed as a hexadecimal number still do not show the AuxType. Since I "tested" my patches in directories which only had named filetypes, I did not see the error.

That was the bad news; the good news is that this month I will complete the job, and give you another simple patch to cause the rest of the AuxTypes to be displayed.

In BASIC.SYSTEM you need to patch $A4F6 (which was $44) to $0E. You can do this with a POKE 42230,14. To put it back, POKE 42230,68. Or to make both last month's and this new change, permanently, do this:

           BLOAD BASIC.SYSTEM,TSYS,A$2000
           POKE 12051,17
           POKE 12022,14
           BSAVE BASIC.SYSTEM,TSYS,A$2000

The corresponding change in SCASM.SYSTEM is a little more difficult, because of the various versions out there. If you found last month's location, this new one is a JMP instruction about 14 lines before that one. Disassembling around $AFD0, you should see:

           CA       DEX
           CA       DEX
           CA       DEX
           CA       DEX
           10 F5    BPL ...
           20 XX XX JSR ...
           4C XX XX JMP ...        patch the JMP address to point
           CA       DEX               to the BIT below.
           BD XX XX LDA ...,X
           20 XX XX JSR ...
           D0 F7    BNE ...
    here   2C XX XX BIT ...

You need to determine the address of the BIT instruction, and make the JMP jump to it. If you are with me this far, I am sure you can figure out the details.

New Version 1.2 of BASIC.SYSTEM | Bob Sander-Cederlof

When I receive a new version of something from Apple, my first impulse is to try to find out exactly what they changed. Especially, when for the first time in four years they update a program so important as BASIC.SYSTEM. And especially when there have been excellent articles published in the last four years clearly describing definite bugs, patches, and work-arounds.

I was very disappointed this morning after carefully analyzing the new version 1.2 of BASIC.SYSTEM. I started by BLOADing the old version 1.1 and then copying it into bank 2 of my IIgs. Then I BLOADed the new version 1.2 and used the monitor V-command to compare the two. There were a total of 24 bytes changed. Thirteen were inside the parameter block for a Get-File-Info call, so their value is irrelevant. One is a byte that is never referenced in any way. Three bytes were changed in the title screen, so that you see "1.2" instead of "1.1", and "COPYRIGHT APPLE 1983-87" instead of "COPYRIGHT APPLE, 1983-84". That leaves only seven bytes in the total update whose change has any significance. They have not fixed even ONE of the many published problems in BASIC.SYSTEM!

So what did they fix? The description sheet that came with the update said they were trying to fix a bug in the CATALOG command. A variable they call TOTENT, which happens to be at BCB9-BCBA, is used for a counter to control the loop which displays files names and info. When the directory is first opened the total number of files in the directory is copied into TOTENT. The original intention of the programmer was to decrement TOTENT after reading each file entry in the directory. When the counter reaches "zero" the catalog should be finished. Unfortunately, the program did not decrement the counter properly.

To make matters worse, the new code in version 1.2 does not fix the original bug. Instead, the patch just omits testing TOTENT altogether. Now if you have a long directory, delete most of the files leaving just a few file names in the first few entries, and CATALOG it in BASIC.SYSTEM, it will read all of the entries anyway. No real problem, just spins the disk a fraction of a second longer.

The original bug was not a very serious problem either. It only failed when the total number of active files in a directory was a multiple of 256, which seldom happens. In fact, it seldom happens that there are that many files in any one directory, because so many of the utilities and even AppleWorks get confused with large directories. The symptom you would see if you had exactly 256 files in a directory, as I understand it, is that you would get an "OUT OF DATA" error message at the end of the catalog instead of the "number of blocks" line. I suppose that could be unnerving, so the bug should be removed if possible.

The faulty decrement code is at the end of the Read Next Catalog Entry subroutine, at $B215, and looks like this:

           B215- DEC $BCB9
           B218- BNE $B21D
           B21A- DEC $BCBA
           B21D- RTS

If the initial number in BCB9 (low byte) and BCBA (high byte) is not a multiple of 256, this code will always result in $BCBA going negative when the total value has been counted down. But if the initial value IS a multiple of 256, it will take an extra 256 times to count it down to a negative value in $BCBA. The end-of-loop test code is at $B09E:

           B09E- LDA $BCBA
           B0A1- BPL $B078

The correct way to decrement the 16-bit value is like this:

           LDA $BCB9
           BNE .1
           DEC $BCBA
       .1  DEC $BCB9

This code results in both bytes being zero when it is counted all the way down. Code to test the TOTENT variable for zero already exists at the top of the loop in BASIC.SYSTEM:

           B070- LDA $BCB9
           B073- ORA $BCBA
           B076- BEQ $B0A3

A little re-structuring of the code would result in even fewer bytes being required to do the decrement and loop control correctly. Instead, we have this strange wipe-out instead. Apple went further, and changed the branch at $B076 to two NOP's, and the error branch following the call to Read Next Catalog Entry to terminate the catalog without error. Very interesting. I wonder if they know something I don't? Maybe the value in the directory which we get TOTENT from is sometimes incorrect? Maybe it is sometimes 0000 when there are really files? Why else NOP-out the instruction at $B076? Well, I have never yet noticed such a problem. Have you? Notice that, with these patches, if you get a disk error when reading a directory block CATALOG will terminate without reporting the error: you just will not see the rest of the files.

The description also claimed to fix a problem which caused the CATALOG to prematurely terminate if a was pressed after a control-S. I have never noticed any such problem in the old version, and was unable to make it happen today. But sure enough, it doesn't fail that way in the new version either. After all, they didn't change any of that code anyway!

Why didn't Apple confer with Ken Kashmarek, Cecil Fretwell, Sandy Mossberg, Don Worth, Pieter Lechner, Dennis Doms or others who have been so carefully analyzing ProDOS and BASIC.SYSTEM over the last four years?

Anyway, after all the above is said, maybe you still wish you had version 1.2. If so, you can turn version 1.1 into 1.2 like this:

           ]BLOAD BASIC.SYSTEM,TSYS,A$2000
           ]CALL-151
           *2282:B2           (was B1         )
           *229A:A0           (was AC         )
           *22A2:B7           (was B4         )
           *3A76:EA EA        (was F0 28      )
           *3A7C:26           (was 3A         )
           *3A9E:EA A9 FF D0  (was AD BA BC 10)
           *3D0G
           ]BSAVE BASIC.SYSTEM,TSYS,A$2000

The new version I have described above came on the newest IIgs system disk. This also included an update to ProDOS-8 called version 1.6. I personally never saw version 1.5, so I compared 1.6 to 1.4. There were way too many differences to determine what they really changed. Most of the differences appear to be due to a reassembly, so that the addresses of nearly everything internal have changed. A list of changes from 1.5 to 1.6 was included with the other documentation, but as I said I never saw version 1.5. Furthermore, after my experience with verson 1.2 of BASIC.SYSTEM, I don't know what to believe. The one major fix they claim in 1.6 is only significant in the IIgs, and has to do with Desk Accessories determining whether ProDOS MLI was busy or not when the Desk Accessory was called up. If you are not using a IIgs, I think I would stick with version 1.4.

The Apple IIx Wish-O-Gram | Jeff Creamer

I have decided to try doing my bit to help dig up the best ideas for what the next edition of the Apple II family ought to be. I'm sending the "Wish-O-Gram" to everyone I can think of who might have some influence on a new Apple II.

In the first Wish-O-Gram I gave my opinions that the the next Apple II should be packed with hardware "horsepower"; be able to emulate the Mac and/or the IBM PC; have standard provisions for 20+ meg hard disk; have an empty socket for a math coprocessor, or one built in; have video output compatible with EGA/VGA monitors.

If any of you readers of Apple Assembly Line have some thoughts on the subject, I would sure like to hear them. Send them to Jeff Creamer, Electronics Technology, Yavapai College, Prescott, AZ 86301.

Apple Assembly Line (ISSN 0889-4302) was published monthly by S-C SOFTWARE CORPORATION, P. O. Box 280300, Dallas, TX 75228 from October, 1980 through May, 1988. Phone (214) 324-2050. This is the final issue. Back issues are $1.80 each for Volumes 1-7, $2.40 each for Volume 8 (plus postage).

All material herein is copyrighted by S-C SOFTWARE CORPORATION, all rights reserved. Unless otherwise indicated, all material herein is authored by Bob Sander-Cederlof. (Apple is a registered trademark of Apple Computer, Inc.)