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 |
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
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 *-------------------------------- |
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 *-------------------------------- |
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 *-------------------------------- |
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.
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 $BCB9This 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 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:
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.
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,
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.)
]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
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).