In This Issue...
What About the New Apple //?
The cloud of rumors surrounding a new, improved, much more powerful Apple // machine is beginning to condense, but there is still no solid public information and no data coming out of Apple. The latest hints indicate that there will be a major announcement sometime this month, so we might all know the answers by the time you read these words.
There is one thing you can be certain of: As soon as we can come out with reliable and accurate details, Apple Assembly Line will be the place to read about how to explore and program this new successor to the computer that all of us have devoted so much to and gotten so much from.
Many of the people we talk to are anticipating an explosion of excitement much like the "good old days" of the original Apple II. They expect the unveiling of such accessable power to rekindle the spirit that drew many of us into computing in the first place: a new world to explore. We hope that's true, and we're going to do our part to help it happen.
The symbol table printed by the S-C Macro Assembler for a long program can be 20 or 30 pages long. Since the assembler allows for labels up to 32 characters long, and values up to 8 hexadecimal digits long, it only prints one label and value per line. Local labels are printed seven to a line, but I am not usually interested in their values anyway. Many times I would like a nice compact listing of only the named labels.
I personally try to stick to relatively short label names, so there would normally be room for four columns of labels in a compact listing. If we say the line length is up to 79 characters (calling it 80 might produce double spacing), that leaves 18 characters per column. I hardly ever have any values which require more than four digits to print in hexadecimal. Allowing for at least one blank between columns, and for a dash between label name and value, that means I have room for names of up to 12 characters long.
I wrote a USR command for the ProDOS version of the S-C Macro Assembler. After it is installed, typing USR causes the named labels to be listed in four columns in alphabetical order. Typing USR2 causes them to be listed in the order of their definition, which for the sake of this discussion I am calling "numerical" order.
I analyzed several symbol tables in memory after different assemblies, and figured out most of the data. The symbol table begins at $1000, with the symbols in the order of their definition in the source code. Each entry has a 2-byte pointer to the next entry beginning with the same letter in alphabetical order. Next is a 4-byte value, with the low byte first. Next is a key byte, which contains a flag bit for whether or not there are local labels under this label, and the length of the label name. Following the key byte there are from 1 to 32 ASCII characters for the label name. If there are any local labels, there are up to 100 pairs of bytes following the label name, terminated by a single $00 byte. The first byte of each pair is the label number in binary + $80. Since local labels are numbered from .0 to .99, the first byte of each pair can have $80 through $E3 in it. The second byte of each pair can have any value from $00 through $FF in it, and is the offset from the named label value.
The pointers at the beginning of each entry are chained alphabetically. There is a separate chain for each starting letter, A through Z. A table beginning at $0132 holds the address of the first symbol for each letter of the alphabet. This makes it easy for my program to list the symbols in alphabetical order, without doing any sorting.
There are two main routines, SYM1 and SYM2, to handle the alphabetic and numeric order. DO.ITEM outputs the name and address for a symbol. NEXT.ITEM.A moves a pointer to the next entry in alphabetical order, while NEXT.ITEM.N does the same in "numerical" order.
I chose $7400 as the origin. The area from $7400 through $77FF is only used by the EXEC command in the ProDOS S-C Macro Assembler. When you assemble the program, the object code will be automatically written on the binary file B.SHORTSYM (because of the .TF directive in line 1030). Thereafter, you can install the USR and USR2 commands by typing "-B.SHORTSYM". It will remain installed until you use the EXEC command or leave the assembler system.
[ It turns out to be quite easy to adapt Harvey's fine program for the DOS version of the assembler. You just need to make the following changes or additions:
1020 .OR $800 or whatever 1200 LOMEM .EQ $4A,4B 1220 USR.VECTOR .EQ $D006 1381 LDA $C083 1382 LDA $C083 1421 LDA $C080
And that's all there is to it! Thanks, Harvey. Bill M. ]
1000 *SAVE S.SHORTSYM 1010 *-------------------------------- 1020 .OR $7400 1030 .TF B.SHORTSYM 1040 *-------------------------------- 1050 * SHORTSYM by Harvey R. Brown 1060 * August 3, 1986 1070 *-------------------------------- 1080 NO.COLUMNS .EQ 4 1090 LINE.LENGTH .EQ 79 1100 *-------------------------------- 1110 PTR .EQ 0,1 1120 ALPH.INDEX .EQ 2 1130 NONZERO .EQ 3 1140 HORIZ .EQ 4 1150 KEY .EQ 5 1160 LENGTH .EQ 6 1170 YSAVE .EQ 7 1180 *-------------------------------- 1190 END.TABLE .EQ $CC,CD 1200 LOMEM .EQ $67,68 WARNING: PRODOS VERSION ONLY 1210 1220 USR.VECTOR .EQ $8006 WARNING: PRODOS VERSION ONLY 1230 *-------------------------------- 1240 IN .EQ $200 1250 ALPHTABLE .EQ $132 ADDRESSES FOR 1ST ENTRY A,B,.. 1260 *-------------------------------- 1270 KEYBD .EQ $C000 1280 STROBE .EQ $C010 1290 *-------------------------------- 1300 PRNTAX .EQ $F941 1310 PRBL2 .EQ $F94A 1320 RDKEY .EQ $FD0C 1330 CROUT .EQ $FD8E 1340 PRBYTE .EQ $FDDA 1350 COUT .EQ $FDED 1360 *-------------------------------- 1370 *-- BRUN OR "-" COMES HERE ------ 1380 SET.UP.USR.VECTOR 1390 LDA #USR.PROCESSOR SET UP USR VECTOR 1400 STA USR.VECTOR+1 1410 LDA /USR.PROCESSOR 1420 STA USR.VECTOR+2 1430 RTS 1440 *-------------------------------- 1450 **-- "USR or USR2 comes here ---- 1460 USR.PROCESSOR 1470 LDY #0 1480 STY HORIZ 0 HORIZ POSITION 1490 .1 INY CHECK INPUT BUFFER FOR OPTION 1500 LDA IN,Y 1510 BEQ SYM1 =$00 is CR (NO OPTION); USE ALPH. 1520 CMP #'2' 1530 BNE .1 OPTION 2 IS SYM2 1540 JMP SYM2 1550 *-------------------------------- 1560 **---SYM1 - ALPH. ORDER --------- 1570 1580 SYM1 LDA #0 SET INDEX TO LETTER A 1590 STA ALPH.INDEX 1600 .1 LDX ALPH.INDEX GET ADDR OF 1ST ITEM 1610 LDA ALPHTABLE,X OF THIS STARTING LETTER 1620 STA PTR FROM S-C ASM TABLE 1630 INX 1640 LDA ALPHTABLE,X HIGH BYTE 1650 PHP 1660 STA PTR+1 1670 INX 1680 STX ALPH.INDEX READY FOR NEXT 1690 PLP 1700 BEQ .3 SKIP IF NO ITEMS THIS LETTER 1710 .2 JSR DO.ITEM PRINT NAME & ADDRESS 1720 JSR NEXT.ITEM.A 1730 BNE .2 FOR EACH ITEM, THIS LETTER 1740 .3 LDX ALPH.INDEX 1750 CPX #50 1760 BCC .1 LOOP 'TILL DONE Z 1770 JMP CROUT PRINT LAST LINE IN PRINTER 1780 *-------------------------------- 1790 **-- SYM2 - NUMERICAL ORDER ----- 1800 1810 SYM2 LDA LOMEM+1 POINT TO START OF TABLE 1820 STA PTR+1 1830 LDA LOMEM 1840 STA PTR 1850 .1 JSR DO.ITEM PRINT NAME & ADDRESS 1860 JSR NEXT.ITEM.N 1870 LDA PTR CHECK FOR END 1880 CMP END.TABLE 1890 LDA PTR+1 1900 SBC END.TABLE+1 1910 BCC .1 LOOP TILL END OF TABLE 1920 JMP CROUT 1930 *-------------------------------- 1940 **------ DO.ITEM ---------------- 1950 1960 DO.ITEM LDY #6 GET KEY 1970 LDA (PTR),Y 1980 *------- PRINT NAME ------------- 1990 AND #%00111111 LOW 6-BITS IS LENGTH 2000 STA LENGTH 2010 .0 INY 2020 LDA (PTR),Y GET CHAR FROM NAME 2030 ORA #$80 HI BIT ON 2040 JSR PRCHAR PRINT IT 2050 DEC LENGTH 2060 BNE .0 LOOP TO END OF NAME 2070 LDA #"-" 2080 JSR PRCHAR 2090 *------ PRINT ADDRESS ----------- 2100 LDA #0 NOTE:32 BITS 2110 STA NONZERO USE THIS TO OMIT LEADING 0'S 2120 LDY #5 2130 STY YSAVE 2140 .1 LDA (PTR),Y GET BYTE OF ADDRESS, HIGH FIRST 2150 BNE .2 2160 LDA NONZERO SKIP LEADING 0 2170 BEQ .3 2180 .2 JSR PRBYTE PRINT BYTE 2190 INC HORIZ 2200 INC HORIZ 2210 INC NONZERO 2220 .3 DEC YSAVE NEXT BYTE LOWER 2230 LDY YSAVE 2240 CPY #3 2250 BCS .1 2260 LDA (PTR),Y ALWAYS DO LOWEST BYTE 2270 JSR PRBYTE 2280 INC HORIZ 2290 INC HORIZ 2300 *----------- TAB ---------------- 2310 LDX #NO.COLUMNS-1 2320 CLC 2330 LDA #0 2340 .4 ADC #LINE.LENGTH/NO.COLUMNS 2350 CMP HORIZ 2360 BEQ .45 2370 BCS .5 FOUND 2380 .45 DEX 2390 BNE .4 TRY NEXT TAB 2400 JSR CROUT MOVE ON TO NEXT LINE 2410 LDA #0 2420 STA HORIZ 2430 BEQ .6 ...ALWAYS 2440 .5 PHA SPACE TO NEXT TAB 2450 SEC 2460 SBC HORIZ 2470 TAX 2480 JSR PRBL2 2490 PLA 2500 STA HORIZ 2510 *------ STOP/START/QUIT --------- 2520 .6 LDA KEYBD STOP UPON KEYPRESS 2530 BPL .7 2540 STA STROBE 2550 JSR RDKEY WAIT FOR 2ND KEYPRESS 2560 CMP #$8D 2570 BNE .7 2580 PLA EXIT ON RETURN 2590 PLA 2600 .7 RTS 2610 **------- PRCHAR ---------------- 2620 PRCHAR STY YSAVE 2630 JSR COUT 2640 INC HORIZ 2650 LDY YSAVE 2660 RTS 2670 **---- NEXT.ITEM.A -------------- 2680 NEXT.ITEM.A 2690 LDY #1 GET ADDR OF NEXT ITEM FROM THIS ONE 2700 LDA (PTR),Y (LEFT BY S-C ASM) 2710 PHA 2720 DEY 2730 LDA (PTR),Y AND LOW 2740 STA PTR 2750 PLA 2760 STA PTR+1 2770 RTS 2780 **---- NEXT.ITEM.N -------------- 2790 NEXT.ITEM.N 2800 LDY #6 GET KEY FROM THIS ITEM 2810 LDA (PTR),Y 2820 PHP SAVE +/- STATUS 2830 AND #%00111111 GET LENGTH OF SYMBOL 2840 CLC 2850 ADC #6 2860 TAY 2870 PLP 2880 BPL .2 SKIP IF NO LOCAL LABELS 2890 .1 INY 2900 LDA (PTR),Y 2910 BEQ .2 2920 INY 2930 BNE .1 ...ALWAYS 2940 *--- 2950 .2 TYA 2960 SEC 2970 ADC PTR 2980 STA PTR 2990 BCC .4 3000 INC PTR+1 3010 .4 RTS 3020 *-------------------------------- |
For years I have been wanting an uninterruptible power supply. Now with a Sider and a large RAMWORKS card, it is almost an imperative. A short interruption of power could easily destroy a full day's work or more. If it occurred while I am writing on the Sider or even on a floppy, it could result in a lot more damage. Other power problems, like spikes which occur during thunderstorms, can cause physical damage to the power supplies in the Apple or its peripherals. I might be able to blame the recent $177 replacement of my Sider power supply on just such a storm.
The reason I haven't bought a UPS before now is the price. Almost all of them are over $500. At last I have found one with most of the features I want, for only $359.
The Minuteman 250, from Para Systems (a local Dallas company), is just right for an Apple II system. It may be right for yours as well. If so, we will send you one for $350 plus freight. Normal freight inside the USA should be under $10. Para Systems makes a full line of UPS products, up to 1000 watts. The Minuteman 250 is rated at 250 watts, and is more than adequate for an Apple II system.
The unit is about an inch larger than a standard Disk II drive in each dimension (it fits nicely under the drive on my system), and weighs 19 pounds. It is heavy for its size, because there is a lot inside: sealed maintenance-free 12-volt battery, inverter and charger electronics, line surge protection, and so on. Normally, power from the AC-line passes through a 3-stage EMI/RFI filter and surge protector directly to your equipment. When the AC-power drops below 95 volts, a battery-powered inverter takes over within four milliseconds. The inverter output is a stepped rectangular wave form, which approximates a sine wave. (Pure sine-wave output costs a lot more, and is not necessary for any equipment I am using.)
There are two outlets, so I plugged my Sider into one and my Apple //e into the other. Usually I have a fan on the side of my //e, from RH Electronics or Kensington Microware. The fan unit plugs into the Minuteman UPS, and powers the Apple //e, an Apple monochrome monitor, and a dot matrix printer. The printer is rated about 60 watts, Sider about 40 watts, monitor about 30 watts, and Apple about 60 watts. That is a total of 190 watts, if the printer is running, or 130 when it is not running. Minuteman can handle a 250-watt load, and maintain full operation for five minutes after the AC input power goes away. If I am not printing, it should maintain full operation of everything else for 15 minutes. That is plenty of time to back up whatever I am working on and turn off the system.
There are a few disadvantages. When AC input power goes away, there is an audible alarm. The alarm is a continuous tone, sounding for the entire time that the AC is off and the battery is powering the system. When the battery has two minutes of charge remaining, the alarm changes to a beep-beep-beep sound. There is no way to shut off the alarm until either AC power comes back on, or you turn off your computer and the UPS. It gets very tiresome. I think there should be a way to either turn off the audible alarm, until the last two minutes of battery power, or at least change it to a short blip once per half-minute or so.
However, in the nine years I have been using Apples, I have not had a serious power outage while my computer was in use. Maybe as many as ten times in nine years there have been very short power outages, most as short as one or two seconds. There have been occasional annoying problems we have blamed on power glitches, spikes, or whatever. The Minuteman should take care of all of these.
The other disadvantage is that when you are leaving the system off and unattended for a long time, you are supposed to remember to turn off the Minuteman. If you leave it on, and AC power goes off for a long time, the battery could be damaged. I don't know how long power would have to be off to damage the battery, since the only power used would be that to run the inverter, but I am guessing it would be at least several hours. It seems to me that there should be a circuit built in to the Minuteman to detect the no-external-load condition, and shut itself off before battery damage could occur.
Even with these disadvantages, I heartily recommend the Minuteman 250. If it even saves me from ONE catastrophic situation, it could pay for itself. As I mentioned above, we will send you one for only $350 plus freight.
Several readers have asked how to automatically execute some file upon starting the ProDOS S-C Macro Assembler, perhaps the Full Screen Editor, perhaps a RAMdisk program, or maybe an EXEC file to install several features. What people want is something analogous to BASIC.SYSTEM's automatic "-STARTUP" feature.
We should be able to patch the assembler's installation code to issue a ProDOS command by stuffing the command into the input buffer, terminated with a Carriage Return, and then calling $BE03 to execute the command. However, not all commands function properly under this approach. The problem here is that the "-" command doesn't work, and the BRUN command seems to depend on how the called program exits. Specifically, when I tried to install my RAMdisk by sending BRUN PRODRIVE the program ran OK, but then crashed into the monitor rather than starting the assembler. A "-" command seemed to be simply ignored. I did find that BRUN FSE to install the Full Screen Editor worked correctly.
The ProDOS books say that you cannot issue the "-" and EXEC commands this way under BASIC.SYSTEM, so I assumed that EXEC would also fail for the assembler. The first version of this article therefore talked only about installing FSE, and suggested carefully testing other programs. At the last minute I decided to actually test EXEC before printing this. IT WORKED!
So, all you have to do is add the following patch to the assembler's installation code and create a text file to issue the commands you want. Here's the SETUP file I use:
- PRODRIVE BLOAD SCASM.SYSTEM,A$2000,TSYS BSAVE /RAM/SCASM.SYSTEM,A$2000,TSYS,L17920 BLOAD BASIC.SYSTEM,A$2000,TSYS BSAVE /RAM/BASIC.SYSTEM,A$2000,TSYS,L10240 BLOAD FILER BSAVE /RAM/FILER,A$1000,L25600
If you want to try this technique with other programs, be sure to start out with a test disk in case of unpredictable results.
You can confirm the address of the SC.INIT routine by checking the JSR instruction at $8000 when the assembler is running. In the assembler's installation routine, $206A is the address of the JMP $8000 instruction that actually starts the assembler.
To install this into the assembler, first boot into the ProDOS S-C Macro Assembler, then do these steps:
:LOAD S.STARTER :BLOAD SCASM.SYSTEM,A$2000,TSYS :ASM :BSAVE SCASM.SYSTEM,A$2000,L17920
If the file length of the assembler is different in the catalog of your disk, use that length in the L parameter.
1000 *SAVE S.STARTER 1010 *-------------------------------- 1020 WBUF .EQ $200 1030 1040 SC.INIT .EQ $830F 1050 DOSCMD .EQ $BE03 1060 *-------------------------------- 1070 .OR $206A 1080 JMP STARTER 1090 1100 .OR $21B0 1110 STARTER 1120 JSR SC.INIT get assembler ready 1130 LDX #0 1140 .1 LDA COMMAND,X 1150 BEQ .2 1160 STA WBUF,X stuff command into buffer 1170 INX 1180 BNE .1 always 1190 1200 .2 JSR DOSCMD do it! 1210 JMP $8003 just in case 1220 *-------------------------------- 1230 COMMAND .AS -/EXEC SETUP/ 1240 .HS 8D00 |
In the June 1986 issue of AAL Bob tried to give the final word on the problem of using BRUN to execute machine language programs which themselves issue DOS commands. His last example, on page 12, still falls short of a complete solution. By adding some code I found in "Beneath Apple DOS", page 6-17, the solution can be complete. The following code can be BRUN either from the keyboard or from within an Applesoft program:
1000 .OR $300 1010 .TF B.SHOW.OFF 1020 *-------------------------------- 1030 PITZ.VERSION 1040 LDA $AA59 SAVE DOS STACK POINTER 1050 PHA ON THE STACK 1060 *-------------------------------- 1070 LDY #0 1080 .1 LDA MSG,Y ISSUE DOS CATALOG COMMAND 1090 JSR $FDED 1100 INY 1110 CPY #MSGSZ 1120 BNE .1 1130 *-------------------------------- 1140 LDA #0 EQUIVALENT TO "NOMON C" 1150 STA $AA5E 1160 PLA RESTORE DOS STACK POINTER 1170 STA $AA59 1180 *-------------------------------- 1190 LDY $76 MSB OF APPLESOFT LINE NUMBER 1200 INY IF WAS $FF, MAKE $00 1210 BEQ .2 ...NOT IN APPLESOFT RUN MODE 1220 LDY $33 PROMPT CHARACTER 1230 CPY #"]" IS IT THE APPLESOFT PROMPT? 1240 BEQ .2 ...YES, SO NOT IN RUN MODE 1250 RTS PROGRAM RUNNING, EXIT WITH "RTS" 1260 .2 JMP $3D0 NOT RUNNING, EXIT THE OTHER WAY 1270 *-------------------------------- 1280 MSG .HS 8D.84 <RETURN>, CTRL-D 1290 .AS -/CATALOG/ 1300 .HS 8D 1310 MSGSZ .EQ *-MSG 1320 *-------------------------------- |
For over a year now a design error has been lurking inside the ProDOS version of the S-C Macro Assembler. Both the assembler and ProDOS itself make extensive use of the standard system input buffer, $200-2FF. During assembly, if you try to direct the object code to more than one target file (using the .TF directive more than one time), things did not go well. The DOS 3.3 version had no such problem.
Following is an example of such a source file. If you type it in and try to assemble it with the ProDOS version, the second and third ".OR" lines will not list properly. In fact, if you have a ProDOS-compatible clock installed, you will see the date and time information instead!
1000 *SAVE S.TEST.FIXTF 1010 *-------------------------------- 1020 .OR $300 1030 .TF B1 1040 X LDA #3 1050 *-------------------------------- 1060 .OR $310 1070 .TF B2 1080 Y LDA #3 1090 *-------------------------------- 1100 .OR $320 1110 .TF B3 1120 Z LDA #3 1130 *-------------------------------- |
After much thought, the only way I can think of to "fix" it is to save the contents of the buffer each time the assembler issues a ProDOS command, and restore the contents afterward. There just happens to be enough room in a "patch" area between $BC00 and $BCFF to do this. The code that needs to be patched may not be in exactly the same location in every copy of the ProDOS version we have sold, so I have written a patching program which will automatically find the exact location and install the patches.
In the following program, a "dummy" section at lines 1800-1940 shows the patched routine. The addresses shown correspond to the latest version. The code shown at $901F-9034 was originally located three bytes lower, at $901C-9031. My patcher moves the code three bytes higher, as shown, and inserts the JSR PATCH1 and JMP PATCH2 code. The PATCH code goes into a free space at $BC00, and the save area is from $BC80 through $BCFF. The patches are actually installed on the image of the SCASM.SYSTEM file, as BLOADed into $2000-$65FF.
Once you have the patching program typed in, the procedure to install the patches is as shown in the comments at the beginning of the program (lines 1020-1060). Just to be sure you have it all right, don't save the patched version on an important disk! Try it out first on a scratch disk, and if everything still works you can update your master copies.
On the other hand, if the whole process seems to laborious or dangerous, send us the original disk of the ProDOS S-C Macro Assembler and we will update it for you. Or, if we have your registration on file you may send $5 and we will send you a fresh disk with the updated version on it.
Many thanks to Richard A. Sims for pointing out this problem to us.
1000 *SAVE FIX.TF.9.8.86 1010 *-------------------------------- 1020 * :LOAD FIX.TF.9.8.86 1030 * :ASM 1040 * :BLOAD SCASM.SYSTEM,TSYS,A$2000 1050 * :$800G 1060 * :BSAVE SCASM.SYSTEM,TSYS,A$2000,L$4600 1070 *-------------------------------- 1080 PNTR .EQ $00,01 1090 *-------------------------------- 1100 PATCH.SC 1110 *---COPY PATCH1, PATCH2 TO $5D00 (IMAGE OF $BC00)--- 1120 LDY #0 1130 .1 LDA BC00,Y 1140 STA $5D00,Y 1150 INY 1160 CPY #BC00.SZ 1170 BCC .1 1180 *---FIND A2.FF.E8.BD.CE BTWN 2000.65FF-------------- 1190 LDA #$2000 1200 STA PNTR 1210 LDA /$2000 1220 STA PNTR+1 1230 .2 LDY #0 1240 .3 LDA (PNTR),Y 1250 CMP STRING,Y 1260 BEQ .4 ...MATCHES SO FAR 1270 INC PNTR 1280 BNE .2 1290 INC PNTR+1 1300 LDA PNTR+1 1310 CMP /$6600 1320 BCC .2 1330 BRK COULD NOT FIND STRING 1340 *** 1350 .4 INY 1360 CPY #STRING.SZ 1370 BCC .3 1380 *---COPY ADDRESS OF PASS.CMD.TO.PRODOS-------------- 1390 LDY #$1A 1400 LDA (PNTR),Y 1410 STA PATCH2-$BC00+$5D00+4 1420 INY 1430 LDA (PNTR),Y 1440 STA PATCH2-$BC00+$5D00+5 1450 *---SHIFT "ISSUE.DOS.COMMAND" 3 BYTES AHEAD--------- 1460 LDY #$15 1470 .5 LDA (PNTR),Y 1480 INY 1490 INY 1500 INY 1510 STA (PNTR),Y 1520 DEY 1530 DEY 1540 DEY 1550 DEY 1560 BPL .5 1570 *---BUILD "JSR PATCH1"------------------------------ 1580 LDY #0 1590 LDA #$20 1600 STA (PNTR),Y 1610 INY 1620 LDA #PATCH1 1630 STA (PNTR),Y 1640 INY 1650 LDA /PATCH1 1660 STA (PNTR),Y 1670 *---BUILD "JMP PATCH2"------------------------------ 1680 LDY #$1A 1690 LDA #PATCH2 1700 STA (PNTR),Y 1710 INY 1720 LDA /PATCH2 1730 STA (PNTR),Y 1740 RTS 1750 *-------------------------------- 1760 STRING .HS A2.FF.E8.BD.CE 1770 STRING.SZ .EQ *-STRING 1780 *-------------------------------- 1790 .DUMMY 1800 .OR $901C 1810 ISSUE.DOS.COMMAND 1820 JSR PATCH1 1830 LDX #-1 1840 .1 INX 1850 LDA $2CE,X 1860 STA $205,X 1870 BNE .1 1880 TAX 1890 .2 INX 1900 INY 1910 LDA $904B,Y 1920 STA $1FF,X 1930 BPL .2 1940 JMP PATCH2 1950 .ED 1960 *-------------------------------- 1970 BC00 .PH $BC00 1980 PATCH1 LDX #0 1990 .1 LDA $200,X 2000 STA $BC80,X 2010 INX 2020 BPL .1 2030 RTS 2033 PATCH2 STX $BE42 ALLOW DEFERRED COMMANDS 2040 JSR *-* $84C2 2050 LDX #127 2060 .3 LDA $BC80,X 2070 STA $200,X 2080 DEX 2090 BPL .3 2100 RTS 2110 .EP 2120 BC00.SZ .EQ *-BC00 2130 *-------------------------------- |
The new ProDOS program selector code published in the July 1986 AAL works very well in most configurations, but not in a slot 3 80-column card such as the Videx card I have. The following modifications allow it to work on an Apple II Plus with a Videx 80-column card:
Original Videx Version 1425 LDA #$99 LDA #$8C 1640 JSR HOME LDA #$8C 1641 -------- JSR COUT 3460 LDA #$FF LDA #$8E 3470 STA INVFLG JSR COUT 4500 LDA #$3F LDA #$8F 4510 STA INVFLG JSR COUT
These same changes may work with most other 80-column cards, including the //c and //e. The only place I am sure they do not work is in 40-columns. Perhaps by squeezing the code somewhere, we could find room to test the byte at $37. If ($37) is $C3, then we are most probably in an 80-column mode, and should use the patched version above; if not $C3, then do it the way Bob originally wrote it.
The "L" command in Wozniak's monitor is one of the great secrets behind Apple's success. "L" has been the key to unlocking many secret doors, enabling programmers to stand on each other's shoulders in their efforts to write all the wonderful software we now enjoy.
Nevertheless, "L" can be improved. We have published at least once before a way to add the ability to specify starting and ending addresses, rather than just living with the built in 20-lines-at-a-time feature. Now that ProDOS is so prevalent, it would be nice if the "L" command could properly handle MLI calls. The three bytes which follow any "JSR $BF00" instruction should be dis-assembled as one hex byte and an address.
The following program adds both of these improvements. It sets up the control-Y monitor command, so that you can disassemble a range of memory. The command can be entered in several formats. In the following examples, "^Y" means "control-Y"
*2000^Y disassemble one instruction *2000.20FF^Y disassemble 2000..20FF *.2300^Y continue and go thru 2300
In the listing which follows, lines 1140-1210 install the control-Y vector, so that that monitor command will call DISASM.BF00.
Lines 1240-1300 move the starting address into PC for the disassembler code, and increment the ending address so it will be easier to check later.
Lines 1320-1400 and 1780-1840 handle normal disassembly, but allow for the option of pausing by pressing any key, or aborting by pressing <RETURN>. If the line disassembled was "JSR $BF00", then lines 1420-1760 disassemble the MLI call number and the address of the MLI parameter block. For example, a disassembled call may look like this:
2000- 20 00 BF JSR $BF00 2003- C1 34 20 .DA #$C1,$2034
Some of you enterprising people who have the source code to the Rak-Ware DISASM may want to add a feature like this to that product, too.
1000 *SAVE S.DISASM.BF00 1010 *-------------------------------- 1020 PC .EQ $3A,3B 1030 A1 .EQ $3C,3D 1040 A2 .EQ $3E,3F 1050 PARMS .EQ $40,41,42 1060 *-------------------------------- 1070 MON.INSTDP .EQ $F8D0 1080 MON.PRBLNK .EQ $F948 1090 MON.PCADJ .EQ $F953 1100 MON.PRYX2 .EQ $FD96 1110 MON.PRBYTE .EQ $FDDA 1120 MON.COUT .EQ $FDED 1130 *-------------------------------- 1140 INSTALL.CTRL.Y.VECTOR 1150 LDA #$4C JMP OPCODE 1160 STA $3F8 1170 LDA #DISASM.BF00 1180 STA $3F9 1190 LDA /DISASM.BF00 1200 STA $3FA 1210 RTS 1220 *-------------------------------- 1230 DISASM.BF00 1240 LDA A1 LOAD STARTING ADDRESS 1250 STA PC 1260 LDA A1+1 1270 STA PC+1 1280 INC A2 ADJUST END ADDRESS 1290 BNE .1 1300 INC A2+1 1310 *-------------------------------- 1320 .1 JSR PAUSE 1330 JSR CHECK.FOR.MLI.CALL 1340 PHP SAVE ANSWER 1350 JSR MON.INSTDP 1360 JSR MON.PCADJ 1370 STA PC 1380 STY PC+1 1390 PLP WAS IT "JSR $BF00"? 1400 BNE .2 ...NO 1410 *-------------------------------- 1420 TAX DO PARMS LINE 1430 JSR MON.PRYX2 ADDR- 1440 JSR MON.PRBLNK 1450 LDY #0 1460 JSR MY.PRBYTE XX XX XX 1470 JSR MY.PRBYTE 1480 JSR MY.PRBYTE 1490 JSR MON.PRBLNK 1500 LDA #"." ".DA" 1510 JSR MON.COUT 1520 LDA #"D" 1530 JSR MON.COUT 1540 LDA #"A" 1550 JSR MON.COUT 1560 JSR MON.PRBLNK 1570 LDA #"#" 1580 JSR MON.COUT 1590 LDA #"$" 1600 JSR MON.COUT 1610 LDA PARMS 1620 JSR MON.PRBYTE 1630 LDA #"," 1640 JSR MON.COUT 1650 LDA #"$" 1660 JSR MON.COUT 1670 LDA PARMS+2 1680 JSR MON.PRBYTE 1690 LDA PARMS+1 1700 JSR MON.PRBYTE 1710 CLC 1720 LDA PC 1730 ADC #3 1740 STA PC 1750 BCC .2 1760 INC PC+1 1770 *-------------------------------- 1780 .2 STA A1 (SET UP FOR ".ENDADDR^Y" CALL) 1790 CMP A2 CHECK IF FINISHED 1800 LDA PC+1 1810 STA A1+1 1820 SBC A2+1 1830 BCC .1 1840 RTS 1850 *-------------------------------- 1860 CHECK.FOR.MLI.CALL 1870 LDY #0 LOOK AHEAD FOR "JSR $BF00" 1880 LDA (PC),Y 1890 CMP #$20 JSR? 1900 BNE .1 ...NO 1910 INY 1920 LDA (PC),Y 1930 BNE .1 ...NOT JSR $BF00 1940 INY 1950 LDA (PC),Y 1960 CMP #$BF 1970 .1 RTS 1980 *-------------------------------- 1990 MY.PRBYTE 2000 LDA (PC),Y 2010 STA PARMS,Y 2020 JSR MON.PRBYTE 2030 LDA #" " 2040 JSR MON.COUT 2050 INY 2060 RTS 2070 *-------------------------------- 2080 PAUSE LDA $C000 2090 BPL .3 2100 STA $C010 2110 CMP #$8D 2120 BEQ .4 ...ABORT 2130 .1 LDA $C000 2140 BPL .1 2150 STA $C010 2160 CMP #$8D 2170 BNE .3 2180 .4 PLA 2190 PLA 2200 .3 RTS 2210 *-------------------------------- |
As I mentioned last month, just as we were wrapping up the August issue I found a reference to another implementation of the "high school" method of taking square roots. By the time I got it ready there was no room left in that issue, so we postponed it 'til now. Most of the variables are the same as those used in the various routines presented last month.
In the May, 1985 issue of Dr. Dobb's Journal, in the 16-Bit Software Toolbox column, Jim Cathey offered a 68000 16-bit edition of the algorithm. What follows is my 6502 8-bit rendition of his approach.
1000 *SAVE S.INTEGER.SQRT 1010 .LIST CON 1020 *-------------------------------- 1030 ARGLO .EQ 0 1040 ARGHI .EQ 1 1050 GUESS .EQ 2 1060 QUOT .EQ 3 1070 REM .EQ 4 1080 ROOT .EQ 5 1090 PROD .EQ 6,7 1100 TRIPS .EQ 8 1110 PREVIOUS.ROOT .EQ 9 1120 BITHI .EQ 10 1130 BITLO .EQ 11 1140 SUBHI .EQ 12 1150 SUBLO .EQ 13 1160 WORKHI .EQ 14 1170 WORKLO .EQ 15 3860 *-------------------------------- 3870 ERRHI .EQ 16 3880 ERRLO .EQ 17 3890 *-------------------------------- 3900 * METHOD DERIVED FROM 68000 CODE IN DDJ MAY 85 3910 * 6502 VERSION AVERAGES 737 CYCLES 3920 *-------------------------------- 3930 SQR3 LDA ARGHI Save working copy of argument 3940 STA WORKHI 3950 LDA ARGLO 3960 STA WORKLO 3970 LDA #0 3980 STA ROOT Start with ROOT = 0 3990 STA ERRHI and ERR = 0 4000 STA ERRLO 4010 *-------------------------------- 4020 LDY #8 8 pairs of bits in argument 4030 .1 ASL WORKLO Two bits out of WORK into ERR 4040 ROL WORKHI 4050 ROL ERRLO 4060 ROL ERRHI 4070 ASL WORKLO 4080 ROL WORKHI 4090 ROL ERRLO 4100 ROL ERRHI 4110 ASL ROOT ROOT = ROOT*2 4120 LDA ROOT BIT = ROOT*2 4130 ASL 4140 STA BITLO 4150 LDA #0 4160 ROL 4170 STA BITHI 4180 LDA ERRLO (CARRY IS CLEAR) 4190 SBC BITLO COMPUTE: ERR-BIT-1 4200 TAX SAVE LO DIFFERENCE 4210 LDA ERRHI 4220 SBC BITHI 4230 BCC .2 ERR < BIT 4240 STA ERRHI 4250 STX ERRLO 4260 INC ROOT ROOT = ROOT+1 4270 .2 DEY 4280 BNE .1 4290 RTS 4300 *-------------------------------- |
I recently learned some more about ProDOS, the hard way. Yes, sometimes catastrophe is indeed the mother of invention, or at least of learning. I was trying to finish typing and saving a program when an electrical storm started. When I did a CATALOG, all the files seemed to be okay, but the footer info at the end about blocks free, used, and total was goofed up. Where I expected 86, 58, and 144, there was instead 681, 64999, and 144.
As an aside, there were only 144 total blocks because the disk is a combination of ProDOS and DOS 3.3, as described in AAL Sep 85 (page 11). But the lesson I learned would apply on regular ProDOS-only disks as well.
Note the logic in the goofed-up numbers: 681+64999 = 144 mod 65536. I suspected that, since everything else was okay, the volume bit map had been messed up. So I inspected the blocks on disk and confirmed my suspicion.
Further, the garbage in the volume bit map block was clearly extraneous, and none of the the good data (the first 144/8=18 bytes) had been changed. The garbage was $DC's in bytes $14A-1C0, inclusive. This is way past the end of the 'real' bytes even for a ProDOS-only disk (35 bytes). But ProDOS must have counted the 1-bits in the $DC bytes as free blocks. Then, subtracting this erroneously large number from 144, it got 64999. Yes! $DC=%11011100, and there are $77=119 such bytes, so that is 5*119=595 more "free" blocks to add to the 86 really free to get 681.
I've read Sandy Mossberg's article about the ProDOS CAT and CATALOG commands (Nibble, May 86), but the arithmetic counting used sectors must be buried deep in the MLI, associated with the GET-FILE-INFO call, according to my Beneath Apple ProDOS book. Apparently ProDOS must count all the 1-bits in the volume bit map blocks as free, regardless of the number of total blocks on the disk. In a way this seems like a bug, but I guess it was just a shortcut in coding.
The lesson I have learned is not to use the "unused" part of the volume bit map to store code, messages, or anything. For a ProDOS-only floppy, only 35 bytes are really used, and 477 bytes are wasted. Nevertheless, do not be tempted to use them. They are set to 0 upon formatting the disk, and ProDOS depends upon them staying that way! I've used the extra bytes in the DOS 3.3 VTOC before, but I had better resist this impulse in ProDOS.
Apple Assembly Line is published monthly by S-C SOFTWARE CORPORATION, P.O. Box 280300, Dallas, Texas 75228. Phone (214) 324-2050. Subscription rate is $18 per year in the USA, sent Bulk Mail; add $3 for First Class postage in USA, Canada, and Mexico; add $14 postage for other countries. Back issues are available for $1.80 each (other countries add $1 per back issue for postage).
All material herein is copyrighted by S-C SOFTWARE CORPORATION,
all rights reserved. (Apple is a registered trademark of Apple Computer, Inc.)