Apple Assembly Line
Volume 8 -- Issue 8May 1988

In This Issue...

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 AssemblersBob 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.3Bob 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 EffectRobert 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 FunctionsSteve 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 CATALOGsBob 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.SYSTEMBob 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-GramJeff 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.)