In This Issue...
Index to Apple Assembly Line
Why haven't we ever published an index to AAL?, you ask. Now that there are three year's worth of back issues to dig through for that article you know you saw a while back, wouldn't a true index come in handy? Well here it is! The 12 center pages of this issue are a complete index to volumes 1 through 3 of Apple Assembly Line. That's October, 1980 through September, 1983, all at your fingertips. The index is placed in the center of this issue so that, if you wish, you can easily remove those pages and store them separately.
More Applesoft Variable Cross Reference
In this issue Louis Pitz presents us with still more tinkering with the old Applesoft Variable Cross Reference. Now that the program has been modified a couple of times, and since it appeared way back in the second issue of Apple Assembly Line, we'll include the complete source code, including all of Louis' enhancements, on the next Quarterly Disk. Remember that all of the back issues are still available, if you don't have Volume 1, Number 2.
New Basis Version 1.1 Available
If any of you are using the S-C Macro Assembler with a Basis 108 computer, Bob Matzinger has adapted version 1.1 for you. Call us for the upgrade price. (214) 324-2050.
Over the years since I bought my Apple I have been collecting various handy modifications to the Apple Monitor. I wanted a convenient way to load up all my patches so that they would be there when I needed them.
Let me point out right now that the following set of patches will NOT work in an Apple //e. They are only for the Apple II Plus monitor. Anyway, several of my favorite patches are already implemented in the Apple //e; the others may fit, but I haven't tried them.
There are two basic ways to get a modified monitor into an Apple. The first requires burning an EPROM with the new version, modifying the motherboard to accept an EPROM in the F8 ROM socket, and plugging it in. (Rather than cutting and splicing the motherboard, a better way is to use a PROMETTE from Computer Micro Works.) The second way is to run out of a language card (16K RAM Card), with a modified monitor at F800 in the RAM card. Some RAM cards may not allow this, leaving the motherboard F8 ROM always switched on, but all the ones I have tried work. If you want to use Applesoft with the modified monitor, or patch Applesoft as well, you can copy it up into the language card too.
I combined my favorite patches with Bill Morgan's patch program (see "PATCHER: General Purpose Patch Installer", AAL, April, 1983) so that BRUNning the program copies the motherboard monitor into a RAM card and then installs all the patches.
The listing that follows uses the .PH and .EP directives found in Version 1.1 of the S-C Macro Assembler. .PH starts a phase, and .EP ends one. At the start of a phase the current assembler origin is saved and the address from the .PH is substituted. Code continues to be assembled into the target file or at the target address, and the saved origin is incremented along with the phase origin. At the end of the phase the saved origin is restored. This allows me to assemble a series of patches with the correct addresses all into one big target file.
Here is a list of my favorite patches:
I included several conditional assembly options, using the .DO, .ELSE, and .FIN directives. These let you select or reject the non-flashing cursor patch and the lowercase display patch. The third option allows you to copy Applesoft from the motherboard along with the monitor, or just the monitor by itself.
1000 *SAVE S.KNOUSE'S MONITOR PATCHES 1010 *-------------------------------- 1020 * 1030 * A COMPILATION OF MONITOR MODIFICATIONS 1040 *-------------------------------- 1050 YES .EQ 1 1060 NO .EQ 0 1070 * 1080 * OPTIONS 1090 * 1100 NFC .EQ YES SET TO YES IF YOU WANT 1110 * A NON-FLASHING CURSOR 1120 LOWERCASE .EQ YES SET TO YES IF YOU CAN 1130 * DISPLAY LOWER CASE 1140 W.APPLESOFT .EQ YES SET TO YES IF YOU WANT 1150 * TO MOVE APPLESOFT WITH 1160 * THE MONITOR, ELSE SET 1170 * TO NO IF YOU ONLY WANT 1180 * TO MOVE AND MODIFY THE 1190 * MONITOR 1200 *-------------------------------- 1210 PNTR .EQ $00,01 1220 PATCH .EQ $02,03 1230 A1L .EQ $3C 1240 A1H .EQ A1L+1 1250 A2L .EQ $3E 1260 A2H .EQ A2L+1 1270 A4L .EQ $42 1280 A4H .EQ A4L+1 1290 BASL .EQ $28 1300 CH .EQ $24 1310 KSWL .EQ $38 1320 *-------------------------------- 1330 COUT .EQ $FDED 1340 CRMON .EQ $FEF6 1350 CROUT .EQ $FD8E 1360 MON.HEADR .EQ $FCC9 1370 MON.MOVE .EQ $FE2C 1380 NXTA1 .EQ $FCBA 1390 PRA1 .EQ $FD92 1400 PRBYTE .EQ $FDDA 1410 PRERR .EQ $FF2D 1420 RDKEY .EQ $FD0C 1430 MON.READ .EQ $FEFD 1440 MON.WRITE .EQ $FECD 1450 *-------------------------------- 1460 ROMR.RAMW .EQ $C081 1470 RAMRW .EQ $C083 1480 *-------------------------------- 1490 * 1500 * GENERAL PURPOSE PATCHER 1510 * 1520 *-------------------------------- 1530 .OR $2D0 1540 .DO W.APPLESOFT 1550 .TF PATCH MONITOR & APPLESOFT 1560 MON.START .EQ $D000 1570 .ELSE 1580 .TF PATCH MONITOR ONLY 1590 MON.START .EQ $F800 1600 .FIN 1610 MON.END .EQ $FFFF 1620 *-------------------------------- 1630 PATCH.MONITOR 1640 LDA #MON.START COPY MONITOR TO RAM CARD 1650 STA A4L 1660 STA A1L 1670 LDA /MON.START 1680 STA A4H 1690 STA A1H 1700 LDA #MON.END 1710 STA A2L 1720 LDA /MON.END 1730 STA A2H 1740 LDA ROMR.RAMW WRITE ENABLE RAM CARD 1750 LDA ROMR.RAMW BY 2 OF THESE 1760 LDY #0 SET UP MON.MOVE 1770 JSR MON.MOVE COPY FROM MOTHERBOARD TO RAMCARD 1780 * 1790 LDA #PATCHES-1 1800 STA PNTR 1810 LDA /PATCHES-1 1820 STA PNTR+1 1830 LDY #0 1840 * 1850 .1 JSR GET.BYTE LENGTH OF NEXT PATCH 1860 BEQ .4 1870 TAX SAVE LENGTH IN X 1880 JSR GET.BYTE GET ADDR OF PATCH 1890 STA PATCH 1900 JSR GET.BYTE 1910 STA PATCH+1 1920 * 1930 .2 JSR GET.BYTE GET A BYTE 1940 STA (PATCH),Y STORE AT DESTINATION 1950 INC PATCH BUMP SOURCE ADDRESS 1960 BNE .3 1970 INC PATCH+1 1980 .3 DEX DECREMENT NUMBER OF BYTES 1990 BNE .2 LOOP FOR MORE 2000 BEQ .1 ... ALWAYS 2010 * 2020 .DO W.APPLESOFT 2030 .4 LDA RAMRW 2040 RTS 2050 .ELSE 2060 .4 RTS 2070 .FIN 2080 *-------------------------------- 2090 GET.BYTE 2100 INC PNTR 2110 BNE .1 2120 INC PNTR+1 2130 .1 LDA (PNTR),Y 2140 RTS 2150 *-------------------------------- 2160 .MA PATCH 2170 ]1.ORG .EQ ]2 2180 .DA #]1.LENGTH 2190 .DA ]1.ORG 2200 .PH ]1.ORG 2210 ]1 2220 .EM 2230 * 2240 .MA ENDP 2250 ]1.END .EQ *-1 2260 ]1.LENGTH .EQ *-]1 2270 .EP 2280 .EM 2290 *-------------------------------- 2300 PATCHES .EQ * 2310 *-------------------------------- 2320 * MONITOR LOWERCASE INPUT ROUTINE 2330 *-------------------------------- 2340 * 2350 *---DON'T STOMP ON LOWERCASE----- 2360 >PATCH NOP.CONVERT,$FD82 2370 AND #$FF DO NOTHING 2380 >ENDP NOP.CONVERT 2390 * 2400 *---MAKE SENSIBLE CURSOR--------- 2410 >PATCH HANDLE.CURSOR,$FBB3 2420 CMP #$E0 IS IT LOWER CASE? 2430 BCS .1 2440 AND #$3F NO - MAKE CHAR INVERSE 2450 .DO NFC 2460 ORA #$00 2470 .ELSE 2480 ORA #$40 THEN FLASHING 2490 .FIN 2500 RTS 2510 .1 AND #$1F CONVERT TO UC INVERSE 2520 RTS 2530 >ENDP HANDLE.CURSOR 2540 * 2550 *---CALL NEW CURSOR ROUTINE------ 2560 >PATCH VEC.HANDLE.CURSOR,$FD11 2570 JSR HANDLE.CURSOR GO TO PATCH 2580 NOP FILL BYTE 2590 >ENDP VEC.HANDLE.CURSOR 2600 *-------------------------------- 2610 * ASCII DUMP 2620 *-------------------------------- 2630 * 2640 *---MODIFIED DUMPER-------------- 2650 >PATCH ASC.DUMP,MON.HEADR 2660 PHA SAVE CHAR 2670 LDA A1L GET LO ADDR BYTE 2680 AND #$07 MOD 8 2690 CLC ADD DISPLACEMENT 2700 ADC #30 OF 30 CHAR 2710 TAY 2720 PLA RECOVER CHARACTER 2730 PHA SAVE IT AGAIN 2740 ORA #$80 FORCE NORMAL VIDEO 2750 CMP #$A0 MAKE CONTROL CHAR INVERSE 2760 BCS .1 ...NOT CONTROL 2770 .DO LOWERCASE 2780 AND #$7F ...CONTROL 2790 .1 STA (BASL),Y PUT ON SCREEN 2800 NOP TO STAY ALIGNED W/ 2810 NOP NON-LOWERCASE CODE 2820 NOP 2830 NOP 2840 NOP 2850 NOP 2860 .ELSE 2870 LDA #$DF MAKE CTRL-CHARS INVERSE 2880 .1 CMP #$E0 IN LOWER CASE RANGE? 2890 BCC .2 ..NO, DISPLAY NORMAL VIDEO 2900 AND #$1F ..YES, FORCE INVERSE VIDEO 2910 .2 STA (BASL),Y STORE IT ON SCREEN 2920 .FIN 2930 LDY #0 RESTORE Y REG 2940 PLA RECOVER BYTE AGAIN 2950 JMP PRBYTE 2960 >ENDP ASC.DUMP 2970 * 2980 *---CALL ASCII DUMP-------------- 2990 >PATCH VEC.ASC.DUMP,$FDBD 3000 JSR ASC.DUMP 3010 >ENDP VEC.ASC.DUMP 3020 *-------------------------------- 3030 * + CURSOR IN ESCAPE MODE 3040 *-------------------------------- 3050 * 3060 *---SAVE SCREEN, SPOT + --------- 3070 >PATCH RDKEY2,ASC.DUMP.END+1 3080 LDY CH SAVE CHARACTER 3090 LDA (BASL),Y 3100 PHA 3110 LDA #'+ PUT AN INVERSE + ON SCREEN 3120 STA (BASL),Y 3130 PLA GET THE CHARACTER BACK 3140 JMP (KSWL) 3150 .BS RDKEY-* FILL W/ 0'S TO RDKEY 3160 >ENDP RDKEY2 3170 * 3180 *---CALL + CURSOR---------------- 3190 >PATCH VEC.RDKEY2.1,$FBA2 3200 JSR RDKEY2 3210 >ENDP VEC.RDKEY2.1 3220 * 3230 *---CALL + CURSOR---------------- 3240 >PATCH VEC.RDKEY2.2,$FD2F 3250 JSR RDKEY2 3260 >ENDP VEC.RDKEY2.2 3270 *-------------------------------- 3280 * MASK BIT CONTROL OVER MEMORY RANGE 3290 * XXYY<ADR1.ADR2W FORMS M=(M.AND.XX).OR.YY 3300 *-------------------------------- 3310 * 3320 >PATCH WRITE,MON.WRITE 3330 LDA (A1L),Y GET A BYTE 3340 AND A4H AND IT WITH XX 3350 ORA A4L OR IT WITH YY 3360 STA (A1L),Y PUT IT BACK 3370 JSR NXTA1 INCR ADDRESS 3380 BCC WRITE LOOP FOR MORE 3390 RTS 3400 .BS CRMON-* FILL W/ 0'S TO CRMON 3410 >ENDP WRITE 3420 *-------------------------------- 3430 * SEARCH 3440 * XXYY<ADR1.ADR2S 3450 *-------------------------------- 3460 * 3470 *---SEARCH PROCESSOR------------- 3480 >PATCH SEARCH,MON.READ 3490 LDA A4H IS THIS A 1 OR 2 BYTE COMPARE 3500 BEQ .2 ..ONE BYTE 3510 LDA A2L ..TWO BYTE 3520 BNE .1 DECREMENT ENDING ADDR 3530 DEC A2H 3540 .1 DEC A2L 3550 * 3560 .2 LDA A4H GET FIRST BYTE TO COMPARE 3570 BEQ .3 IF ZERO DO A ONE BYTE SEARCH 3580 CMP (A1L),Y COMPARE WITH MEMORY 3590 BNE .4 NOT EQUAL - GO TO NEXT BYTE 3600 INY GET NEXT BYTE 3610 .3 LDA (A1L),Y 3620 LDY #0 RESTORE Y REG 3630 CMP A4L COMPARE 3640 BNE .4 NOT EQUAL - DRIVE ON 3650 JSR PRA1 3660 .4 JSR NXTA1 GET NEXT BYTE 3670 BCC .2 LOOP FOR MORE 3680 RTS 3690 .BS PRERR-* FILL W/ 0'S TO PRERR 3700 >ENDP SEARCH 3710 * 3720 *---PATCH COMMAND TABLE---------- 3730 >PATCH VEC.SEARCH,$FFDE 3740 .DA #$EC 'S' EOR $B0 + $89 3750 >ENDP VEC.SEARCH 3760 *-------------------------------- 3770 .DA #0 END OF PATCHES 3780 *-------------------------------- 3790 END .EQ *-1 3800 LENGTH .EQ END-PATCH.MONITOR+1 3810 .LIST OFF |
I finally figured out how to modify the Applesoft Variable Cross Reference (from the November, 1980 AAL) to distinguish between defined functions and array variables. As Bob mentioned at that time, VCR tags an occurence of FN AB(whatever) as an appearance of the array variable AB().
It turns out that the changes needed aren't many, and are compatible with my tinkering in the August '83 AAL, which added 80-column output to a printer.
As VCR is scanning for variables, in the GET.NEXT.VARIABLE section, add the check for the FN token in lines 2132-2134. If found, go to lines 2222-2228 to set a flag and go back to get the NEXT.CHAR.NOT.QUOTE. Unless the Applesoft program is in error, a variable name immediately follows the FN token.
In PACK.VARIABLE.NAME, the program distinguishes variables by VARNAM+2 having a space, $, or %. Array variables have the high bit set. In lines 2791-2796 I set apart FN variables by placing a dash (-) with the high bit set in VARNAM+2. This will make FN types come after the others alphabetically.
Now we come to the printing stage, in PRINT.LETTER.CHAIN. There the variable name (and dash, in case of FN types) is printed. If the high bit of VARNAM+2 is set, lines 4292-4294 check for the dash value. If so, skip to lines 4511-4515 and print out "FN" also.
This way, FN AB will come out as "AB-FN", which is a bit of a cop-out on my part. But I opted for making minimal changes to VCR to keep things simple.
If you play with long programs also having defined functions, as I have, these additions to VCR should help.
[ Now that the Variable Cross Reference program has been modified a couple of times, and since it appeared way back in the second issue of Apple Assembly Line, we'll include the complete source code, including all of Louis' enhancements, on the next Quarterly Disk. Remember that all of the back issues are still available, if you don't have Volume 1, Number 2. ...Bill ]
2132 CMP $#C2 2134 BEQ .4 2222 .4 STA $7 set FLAG2 2224 BEQ .1 ...always 2226 * unless syntax error, NEXT.CHAR.NOT.QUOTE 2228 * will be letter, hence variable! 2791 LDA $7 recall FLAG2 2792 CMP #$C2 FN token? 2793 BNE .5 (to RTS) 2794 LDA #'-+80 "-" 2795 STA VARNAM+2 to indicate FN 2796 STA $7 and reset FLAG2 4292 CMP #$AD not array, but FN? 4294 BEQ .6 4511 .6 LDA #'F add 'FN' after 4512 JSR PRINT.CHAR 4513 LDA #'N variable name 4514 JSR PRINT.CHAR 4515 BNE .4 ...always
Here is the complete program with the revisions in line:
1000 *--------------------------------- 1010 * VARIABLE CROSS REFERENCE 1020 * FOR APPLESOFT PROGRAMS 1030 *--------------------------------- 1040 ZZ.BEG .EQ $8800 1050 .OR ZZ.BEG 1060 .TF B.VCRP 1070 *--------------------------------- 1080 LDA #$4C AMPERSAND VECTOR 1090 STA $3F5 1100 LDA #VCR 1110 STA $3F6 1120 LDA /VCR 1130 STA $3F7 1140 RTS 1150 *--------------------------------- 1160 PNTR .EQ $18,19 POINTER INTO PROGRAM 1170 DATA .EQ $1A THRU $1D 1180 LZFLAG .EQ $1A LEADING ZERO FLAG 1190 NEXTLN .EQ $1A,1B ADDRESS OF NEXT LINE 1200 LINNUM .EQ $1C,1D CURRENT LINE NUMBER 1210 STPNTR .EQ $1E,1F POINTER INTO VARIABLE TABLE 1220 TPTR .EQ $9B,9C TEMP POINTER 1230 SYMBOL .EQ $9D THRU $A4 8 BYTES 1240 VARNAM .EQ SYMBOL+1 1250 HSHTBL .EQ $280 1260 ENTRY.SIZE .EQ $A5,A6 1270 *--------------------------------- 1280 PRGBOT .EQ $67,68 BEGINNING OF PROGRAM 1290 LOMEM .EQ $69,6A BEGINNING OF VARIABLE SPACE 1300 EOT .EQ $6B,6C END OF VARIABLE TABLE 1310 *--------------------------------- 1320 TKN.REM .EQ 178 1330 TKN.DATA .EQ 131 1340 *--------------------------------- 1350 MON.CH .EQ $24 1360 MON.PRBL2 .EQ $F94A 1370 MON.COUT .EQ $FDED 1380 MON.CROUT .EQ $FD8E 1390 *--------------------------------- 1400 VCR 1410 JSR INITIALIZATION 1420 .1 JSR PROCESS.LINE 1430 BNE .1 UNTIL END OF PROGRAM 1440 JSR PRINT.REPORT 1450 JSR INITIALIZATION ERASE VARIABLE TABLE 1452 LDA #0 CLEAR $A4 SO APPLESOFT WILL 1454 STA $A4 WORK CORRECTLY 1460 RTS 1470 *--------------------------------- 1480 INITIALIZATION 1490 LDA LOMEM 1500 STA EOT 1510 LDA LOMEM+1 1520 STA EOT+1 1530 LDX #52 # OF BYTES FOR HASH POINTERS 1540 LDA #0 1550 .1 STA HSHTBL-1,X 1560 DEX 1570 BNE .1 1580 LDA PRGBOT 1590 STA PNTR 1600 LDA PRGBOT+1 1610 STA PNTR+1 1620 RTS 1630 *--------------------------------- 1640 PROCESS.LINE 1650 LDY #3 CAPTURE POINTER AND LINE # 1660 .1 LDA (PNTR),Y 1670 STA DATA,Y 1680 DEY 1690 BPL .1 1692 LDA DATA+1 CHECK IF END 1694 BEQ .3 YES 1700 CLC SKIP OVER DATA 1710 LDA PNTR 1720 ADC #4 1730 STA PNTR 1740 BCC .2 1750 INC PNTR+1 1760 .2 JSR SCAN.FOR.VARIABLES 1770 LDA DATA 1780 STA PNTR 1790 LDA DATA+1 1800 STA PNTR+1 1810 * BNE .3 1820 .3 RTS 1830 *--------------------------------- 1840 SCAN.FOR.VARIABLES 1850 .1 JSR GET.NEXT.VARIABLE 1860 BEQ .3 END OF LINE 1870 JSR PACK.VARIABLE.NAME 1880 JSR SEARCH.VARIABLE.TABLE 1890 BCC .2 FOUND SAME VARIABLE 1900 LDA #0 1910 STA SYMBOL+4 START OF LINE NUMBER CHAIN 1920 STA SYMBOL+5 1930 LDA LINNUM+1 MSB FIRST 1940 STA SYMBOL+6 1950 LDA LINNUM 1960 STA SYMBOL+7 1970 LDA #8 ADD 8 BYTE ENTRY 1980 JSR ADD.NEW.ENTRY 1990 JMP .1 2000 .2 JSR SEARCH.LINE.CHAIN 2010 BCC .1 FOUND SAME LINE NUMBER 2020 LDA #4 ADD 4 BYTE ENTRY 2030 JSR ADD.NEW.ENTRY 2040 JMP .1 2050 .3 RTS 2060 *--------------------------------- 2070 GET.NEXT.VARIABLE 2080 .1 JSR NEXT.CHAR.NOT.QUOTE 2090 BEQ .2 END OF LINE 2100 CMP #TKN.DATA 2110 BEQ .3 2120 CMP #TKN.REM 2130 BEQ .2 SKIP TO NEXT LINE 2132 CMP #$C2 FN token? 2134 BEQ .4 2140 JSR LETTER LETTER? 2150 BCC .1 NO, KEEP LOOKING 2160 .2 RTS 2170 * DATA, SO SKIP TO NEXT STATEMENT 2180 .3 JSR NEXT.CHAR.NOT.QUOTE 2190 BEQ .2 EOL, RETURN 2200 CMP #': COLON? 2210 BNE .3 NOT END YET 2220 BEQ .1 ...ALWAYS 2222 .4 STA $7 set FLAG2 2224 BEQ .1 ...always 2226 * unless syntax error, NEXT.CHAR.NOT.QUOTE 2228 * will be letter, hence variable! 2230 *--------------------------------- 2240 NEXT.CHAR.NOT.QUOTE 2250 .1 JSR NEXT.CHAR 2260 BEQ .2 EOL, RETURN 2270 CMP #'" QUOTE? 2280 BEQ .3 YES, SCAN OVER QUOTATION 2290 .2 RTS RETURN 2300 .3 JSR NEXT.CHAR 2310 BEQ .2 EOL, RETURN 2320 CMP #'" TERMINAL QUOTE? 2330 BNE .3 NOT YET 2340 BEQ .1 ...ALWAYS 2350 *--------------------------------- 2360 * NEXT CHARACTER FROM LINE 2370 * CALL: JSR NEXT.CHAR 2380 * RETURN: (A)=CHAR FROM LINE 2390 * IF CHAR .NE. EOL, 2400 * INCREMENT PNTR AND 2410 * STATUS Z=0 2420 * IF CHAR .EQ. EOL, 2430 * STATUS Z=1 2440 *--------------------------------- 2450 NEXT.CHAR 2460 LDY #0 2470 LDA (PNTR),Y 2480 BEQ .1 EOL 2490 INC PNTR BUMP POINTER 2500 BNE .1 2510 INC PNTR+1 2520 .1 RTS 2530 *--------------------------------- 2540 PACK.VARIABLE.NAME 2550 STA VARNAM FIRST CHAR OF NAME 2560 LDA #' BLANKS FOR OTHER TWO CHARS 2570 STA VARNAM+1 2580 STA VARNAM+2 2590 JSR NEXT.CHAR 2600 BEQ .5 END OF LINE 2610 JSR LTRDIG 2620 BCC .2 NOT LETTER OR DIGIT 2630 STA VARNAM+1 2640 .1 JSR NEXT.CHAR IGNORE EXCESS NAME 2650 BEQ .5 END OF LINE 2660 JSR LTRDIG 2670 BCS .1 LETTER OR DIGIT 2680 .2 CMP #'$ DOLLAR SIGN? 2690 BEQ .3 YES 2700 CMP #'% PER CENT? 2710 BNE .4 NO 2720 .3 STA VARNAM+2 2730 JSR NEXT.CHAR 2740 BEQ .5 END OF LINE 2750 .4 CMP #'( LEFT PAREN? 2752 BEQ .6 YES 2754 CMP #'" QUOTE? 2760 BNE .5 NO 2762 LDA PNTR YES, BACK UP POINTER 2763 BNE .7 2764 DEC PNTR+1 2765 .7 DEC PNTR 2766 RTS 2770 .6 LDA VARNAM+2 SET HIGH BIT 2780 ORA #$80 TO FLAG ARRAY 2790 STA VARNAM+2 REFERENCE 2791 LDA $7 recall FLAG2 2792 CMP #$C2 FN token? 2793 BNE .5 (to RTS) 2794 LDA #'-+$80 "-" 2795 STA VARNAM+2 to indicate FN 2796 STA $7 and reset FLAG2 2800 .5 RTS 2810 *--------------------------------- 2820 SEARCH.VARIABLE.TABLE 2830 SEC CONVERT 1ST CHAR TO 2840 LDA VARNAM HASH TABLE INDEX 2850 SBC #'A 2860 ASL 2870 ADC #HSHTBL 2880 STA STPNTR 2890 LDA /HSHTBL 2900 ADC #0 2910 STA STPNTR+1 2920 *--- FALL INTO CHAIN SEARCH ROUTINE 2930 *--------------------------------- 2940 CHAIN.SEARCH 2950 .1 LDY #0 POINT AT POINTER IN ENTRY 2960 LDA (STPNTR),Y 2970 STA TPTR 2980 INY 2990 LDA (STPNTR),Y 3000 BEQ .4 END OF CHAIN, NOT IN TABLE 3010 STA TPTR+1 3020 LDX #2 2 MORE CHARS IN SYMBOL 3030 LDY #2 POINT AT NAME IN ENTRY 3040 .2 LDA (TPTR),Y COMPARE NAMES 3050 CMP SYMBOL,Y 3060 BCC .3 NOT THIS ONE, BUT KEEP LOOKING 3070 BNE .4 NOT IN THIS CHAIN 3080 DEX 3090 BEQ .5 NAME IS THE SAME 3100 INY NEXT BYTE PAIR 3110 BNE .2 ...ALWAYS 3120 *--------------------------------- 3130 .3 JSR .5 UPDATE POINTER, CLEAR CARRY 3140 BCC .1 ...ALWAYS 3150 *--------------------------------- 3160 .4 SEC DID NOT FIND 3170 RTS 3180 *--------------------------------- 3190 .5 LDA TPTR 3200 STA STPNTR 3210 LDA TPTR+1 3220 STA STPNTR+1 3230 CLC 3240 RTS 3250 *--------------------------------- 3260 ADD.NEW.ENTRY 3270 STA ENTRY.SIZE 3280 CLC SEE IF ROOM 3290 LDX #1 3300 LDY #0 3310 STY ENTRY.SIZE+1 3320 .1 LDA (STPNTR),Y GET CURRENT POINTER 3330 STA SYMBOL,Y 3340 LDA EOT,Y 3350 STA (STPNTR),Y 3360 STA TPTR,Y 3370 ADC ENTRY.SIZE,Y 3380 STA EOT,Y 3390 INY 3400 DEX 3410 BPL .1 3420 *--- SEE IF GOING TO BE ENOUGH ROOM 3430 LDA EOT 3440 CMP #ZZ.BEG 3450 LDA EOT+1 3460 SBC /ZZ.BEG 3470 BCS .3 MEM FULL ERR 3480 *--- MOVE ENTRY INTO VARIABLE TABLE 3490 LDY ENTRY.SIZE 3500 DEY 3510 .2 LDA SYMBOL,Y 3520 STA (TPTR),Y 3530 DEY 3540 BPL .2 3550 LDA TPTR 3560 STA STPNTR 3570 LDA TPTR+1 3580 STA STPNTR+1 3590 RTS 3600 .3 JMP MEM.FULL.ERR 3610 MEM.FULL.ERR 3620 BRK 3630 *--------------------------------- 3640 SEARCH.LINE.CHAIN 3650 CLC ADJUST POINTER TO START 3660 LDA STPNTR OF LINE # CHAIN 3670 ADC #4 3680 STA SYMBOL 3690 LDA STPNTR+1 3700 ADC #0 3710 STA SYMBOL+1 3720 LDA #SYMBOL 3730 STA STPNTR 3740 LDA /SYMBOL 3750 STA STPNTR+1 3760 LDA LINNUM PUT LINE NUMBER INTO SYMBOL 3770 STA SYMBOL+3 3780 LDA LINNUM+1 3790 STA SYMBOL+2 3800 JMP CHAIN.SEARCH 3810 *--------------------------------- 3820 PRINT.REPORT 3830 LDA #'A START WITH A'S 3840 .1 STA VARNAM 3850 SEC 3860 SBC #'A CONVERT TO HSHTBL INDEX 3870 ASL 3880 TAY 3890 LDA HSHTBL+1,Y 3900 BEQ .2 NO ENTRY FOR THIS LETTER 3910 STA PNTR+1 3920 LDA HSHTBL,Y 3930 STA PNTR 3940 JSR PRINT.LETTER.CHAIN 3950 .2 INC VARNAM NEXT LETTER 3960 LDA VARNAM 3970 CMP #'Z+1 3980 BCC .1 STILL MORE LETTERS 3990 RTS FINISHED 4000 *--------------------------------- 4010 LTRDIG 4020 CMP #'0 DIGIT? 4030 BCC LD1 NO 4040 CMP #'9+1 4050 BCC LD2 YES 4060 LETTER 4070 CMP #'A LETTER? 4080 BCC LD1 NO 4090 CMP #'Z+1 4100 BCC LD2 YES 4110 CLC NO 4120 LD1 RTS 4130 LD2 SEC 4140 RTS 4150 *--------------------------------- 4160 PRINT.LETTER.CHAIN 4170 .1 LDA VARNAM FIRST LETTER 4180 JSR PRINT.CHAR 4190 LDY #1 4200 .2 INY 4210 LDA (PNTR),Y REST OF NAME 4220 AND #$7F 4230 CMP #' BLANK? 4240 BEQ .3 4250 JSR PRINT.CHAR 4260 .3 CPY #3 4270 BCC .2 4280 LDA (PNTR),Y CHECK IF ARRAY 4290 BPL .4 4292 CMP #$AD not array, but FN? 4294 BEQ .6 4300 LDA #'( 4310 JSR PRINT.CHAR 4320 .4 CLC POINT AT LINE # CHAIN 4330 LDA PNTR 4340 ADC #4 4350 STA TPTR 4360 LDA PNTR+1 4370 ADC #0 4380 STA TPTR+1 4390 JSR PRINT.LINNUM.CHAIN 4400 JSR MON.CROUT 4410 LDY #1 4420 LDA (PNTR),Y POINTER TO NEXT VARIABLE 4430 BEQ .5 NO MORE 4440 PHA 4450 DEY 4460 LDA (PNTR),Y 4470 STA PNTR 4480 PLA 4490 STA PNTR+1 4500 BNE .1 ...ALWAYS 4510 .5 RTS 4511 .6 LDA #'F add 'FN' after 4512 JSR PRINT.CHAR 4513 LDA #'N variable name 4514 JSR PRINT.CHAR 4515 BNE .4 ...always 4520 *--------------------------------- 4530 PRINT.LINNUM.CHAIN 4534 LDA #0 reset counter to 0 4538 STA $6 for each variable 4540 .1 JSR TAB.NEXT.COLUMN 4550 LDY #2 POINT AT LINE # 4560 LDA (TPTR),Y 4570 STA LINNUM+1 4580 INY 4590 LDA (TPTR),Y 4600 STA LINNUM 4610 JSR PRINT.LINE.NUMBER 4620 LDY #1 SET UP NEXT POINTER 4630 LDA (TPTR),Y 4640 BEQ .2 4650 PHA 4660 DEY 4670 LDA (TPTR),Y 4680 STA TPTR 4690 PLA 4700 STA TPTR+1 4710 BNE .1 ...ALWAYS 4720 .2 RTS 4730 *--------------------------------- 4740 TAB.NEW.LINE 4750 JSR MON.CROUT 4760 TAB.NEXT.COLUMN 4770 .1 LDA #7 FIRST TAB STOP 4780 .2 CMP MON.CH CURSOR POSITION 4790 BCS .3 PERFORM TAB 4800 ADC #6 NEXT TAB STOP 4810 CMP #33 END OF LINE? 4820 BCC .2 4821 INC $6 count the screen line 4822 LDA $6 4823 AND #1 look at odd-even bit 4824 BEQ TAB.NEW.LINE both scrn and printer 4834 LDA #$8D 4835 JSR $FDF0 <CR> to screen only 4836 JMP .1 ...always 4840 .3 BEQ .4 ALREADY THERE 4850 SBC MON.CH CALCULATE # OF BLANKS 4860 TAX 4870 JSR MON.PRBL2 4880 .4 RTS 4890 *--------------------------------- 4900 PRINT.LINE.NUMBER 4910 LDX #4 PRINT 5 DIGITS 4920 STX LZFLAG TURN ON LEADING ZERO FLAG 4930 .1 LDA #'0 DIGIT=0 4940 .2 PHA 4950 SEC 4960 LDA LINNUM 4970 SBC PLNTBL,X 4980 PHA 4990 LDA LINNUM+1 5000 SBC PLNTBH,X 5010 BCC .3 LESS THAN DIVISOR 5020 STA LINNUM+1 5030 PLA 5040 STA LINNUM 5050 PLA 5060 ADC #0 INCREMENT DIGIT 5070 BNE .2 ...ALWAYS 5080 .3 PLA 5090 PLA 5100 CMP #'0 5110 BEQ .5 ZERO, MIGHT BE LEADING 5120 SEC TURN OFF LZFLAG 5130 ROR LZFLAG 5140 .4 JSR PRINT.CHAR 5150 DEX 5160 BPL .1 5170 RTS 5180 .5 BIT LZFLAG LEADING ZERO FLAG 5190 BMI .4 NO 5200 LDA #' BLANK 5210 BNE .4 ...ALWAYS 5220 PLNTBL .DA #1 5230 .DA #10 5240 .DA #100 5250 .DA #1000 5260 .DA #10000 5270 PLNTBH .DA /1 5280 .DA /10 5290 .DA /100 5300 .DA /1000 5310 .DA /10000 5320 *--------------------------------- 5330 PRINT.CHAR 5340 ORA #$80 5350 JSR MON.COUT 5360 RTS 5370 *--------------------------------- 5380 ZZ.END .EQ * 5390 ZZ.SIZ .EQ ZZ.END-ZZ.BEG |
Steve Knouse called to thank us for printing his Generic Screen Dump program last month, and to chew us out for garbling it.
It seems that we edited and renumbered the code, but didn't update the line number references in the text.
Here's a table to translate what the article says into what it means:
Says Means 1610 1100 2030 1460 2190 1620 2250 1680 2260 1690 2270 1700 2280 1710 2290 1720 2300 1730 2310 1740
Sorry about that, readers. Sorry about that, Steve.
[ And another last-minute correction -- the TAY instruction in line 1510 should be a TYA. ]
It has been nearly two years since we raised the price of a subscription from $12 to $15 per year, and now we are forced to another increase. Effective January 1, 1984, a year's subscription by bulk mail in the USA will be $18. For First Class Mail in the USA, Canada, and Mexico, add $3. Subscriptions to other countries, including postage, will be $30 per year.
You can beat the price by renewing early. All renewals received before January 1st will be at the old rates.
Now for some good news! We want to reduce our inventory of back issues, so we are offering some special prices. We normally sell them for $1.50 each; between now and January 1st you can buy them for only $1 each!
We want to encourage more of you to save your time and energy by getting the Quarterly Disks, with all the source code from three issues already correctly entered. Each Quarterly Disk costs only $15. To save even more trouble, and some $$$, you can subscribe to the Quarterly Disks. Effectively immediately, prepaid subscriptions for four Quarterly Disks will be only $45. You save 25%!
Continuing in the Christmas spirit, here are some more specials good through the end of this year, only for subscribers to Apple Assembly Line:
Regular Special FLASH! Integer BASIC Compiler $79 $50 The Visible Computer: 6502 $50 $40 ES-CAPE $60 $40 S-C Math Disk & Game Disk Set $35 $20 Laumer's Full Screen Editor $49 $40
I suppose it had to happen at least once in three years, but it still came as a shock.
Last June I wrote and published a program and article called Amper-Monitor, and then I did it all over again for the September issue. The programs are slightly different, both in design and implementation, but they still do the same thing.
Maybe now that we have a complete index to the first three volumes I won't make this mistake again.
I have found a solution to ScreenWriter II's long boot-up time (which is one of my few complaints with the product). Would you believe a reduction from 46 seconds to just under 14 seconds?
The solution was given in a patch to DOS 3.3 given by Paul Schlyter and Bob Sander-Cederlof in the April 1983 issue of AAL. Since ScreenWriter's DOS is nearly identical to 3.3, I was inspired to try the patch (on ONE of my two copy-protected original disks) -- and it worked!
I installed the patch between lines 50 and 60 of APP2 (ScreenWriter's customizeable startup program). The POKEs will only be performed at startup -- if you look closely at APP2, you'll see that the POKEing lines will be skipped when the program is used to switch between Editor and Runoff in the non-RAMcard version.
To install the patch, do the following: 1. From BASIC, LOAD APP2 2. Type in Lines 51 - 59, carefully! 3. SAVE APP2 4. RUN CUSTOMIZEA
That's it! You will now have a fast-booting ScreenWriter. You may also want to do this to some of your normal DOS 3.3 disks -- the patch is in an unused area of DOS, and seems to coexist happily with everything else I tried (like PLE and GPLE for instance). Exception: in the //e version of DOS 3.3, the patch screws up the infamous APPEND command -- no great loss, in my opinion.
51 READ N: IF N=0 THEN 59:REM Make this "THEN 60" (60 is the next ScreenWriter II line) when line 59 is DELETEd 52 READ A: SUM = SUM + A + N 53 FOR I = 1 TO N: READ P: POKE A,P: A=A+1: SUM=SUM+P: NEXT 54 GOTO 51 55 DATA 44, 47721, 173, 230, 181, 208, 36, 173, 194, 181, 240, 31, 173, 203, 181, 72, 173, 204, 181, 72, 173, 195, 181, 141, 203, 181, 173, 196, 181, 141, 204, 181, 32, 182, 176, 176, 3, 76, 223, 188, 76, 111, 179, 76, 150, 172 56 DATA 33, 48351, 238, 228, 181, 208, 3, 238, 229, 181, 238, 196, 181, 238, 204, 181, 206, 194, 181, 208, 11, 104, 141, 204, 181, 104, 141, 203, 181, 76, 150, 172, 76, 135, 186 57 DATA 2, 44198, 105, 186 58 DATA 0 59 IF SUM <> 153114 THEN PRINT "OOPS! DATA IS OFF BY "153114-SUM: STOP: REM (Delete this line when you are SURE it works!)
I liked the procedure for getting listings into a text file during assembly (AAL July '83). However, it won't work if the file is too large and requires .IN directives. I recently did a large assembly using the following source code:
0 .DU 1 .TF LISTING 2 .IN PART1 3 .IN PART2 4 .ED
What I expected to get was a 356-sector text file on disk, but all I got was a 2-sector file -- the code for PART1 and PART2 was not sent to the disk (they did list to the screen!)
I first tried to solve my particular problem by making more RAM available for the assembly by moving the Symbol Table base down to $400. I thought that should work, since I use an 80-column card and not the Apple's text screen. However, the assembler and the system monitor had other ideas, and promptly destroyed the symbol table by scrolling the screen memory.
However, I did manage to get my large assembly listing to go to disk as a text file -- by doing it in two parts. I used a utility program from the assembler disk to give each part the missing label definitions from the other part.
The steps are as follows:
1) Assemble the code normally with .IN directives.
0001 .IN PART1 0002 .IN PART2
2) BRUN B.MAKE EQUATE FILE (from the S-C Macro Version 1.1 Disk.) That creates a file of .EQ statements called SYMBOLS which contains all the normal labels and values from the Symbol Table in memory.
3) Merge SYMBOLS with PART1 and delete all duplicate labels from the SYMBOLS section.
4) Assemble PART1 using the .DU-.TF-.ED trick, and using .LIST OFF/ON so that the SYMBOLS section does not write to the text file.
5) Repeat steps 3 and 4 on PART2.
It is a bit laborious deleting all the duplicate labels in the two assemblies. I hope someone can suggest a patch to the assembler to prevent it from reporting "EXTRA DEFINITION ERROR". That certainly would make this listing process easier.
No sooner said...
OK, here are some patches to defeat the check for double definitions in the S-C Macro Assemblers. Just put an RTS ($60) at the appropriate location:
Version 1.0 -- Motherboard: $221D Language Card: $E369
Version 1.1 -- Motherboard: $210E Language Card: $E228
Be very certain that any double definitions are intentional and identical. If you use the same label with two different values (unless it's defined with .SE) the assembler cannot produce correct code.
A simple one-byte patch will enable you to use lower-case letters inside .TI titles. There are eight versions of the assembler on the Version 1.1 release disk, and the byte to be changed is in a different place for each version.
The code for the .TI directive looks the same wherever it is located. Here is a hex dump of the code, with a square around the byte to be changed:
A2 00 LDX #0 20 3E x2 JSR $123E or $D23E C9 2C CMP #$2C D0 0D BNE ... 20 3E x2 JSR $123E or $D23E B0 08 BCS ... 9D 70 01 STA $170,X
The following table shows the address of the byte to be changed:
File Name x = 1000 x = D000 -------- -------- S-C.ASM.MACRO.x $2CE6 $EE00 S-C.ASM.MACRO.x.E $2CC2 $EDDC S-C.ASM.MACRO.x.STB80 $2DDA $EEFD S-C.ASM.MACRO.x.VIDEX $2DB1 $EED4
Once you find the right byte, which contains $3E, change it to $4E. (Remember to change a byte in the RAM card you need to write-enable it first.)
Sometimes we want to get an assembly listing that doesn't use up half a page of paper for each .AS or .HS line, listing three object bytes on each line. A number of you have asked for a patch to show the source line without listing each and every one of those hex bytes.
Well, David Roberts, a subscriber in Australia, has come up with a simple way to do just that. He uses macros! David suggests these definitions:
.MA AS .AS -"]1" .EM .MA AT .AT "]1" .EM .MA HS .HS "]1" .EM
Now you can code text with >AS "THIS IS MY STRING", and use the .LIST MOFF option to suppress the hex listing. That's really a "why didn't I think of that?" Thanks, David.
The word is that the new Macintosh machine from Apple is going to be 68000-based and affordable. I know that I am going to want one, and I would like to get a leg up on learning the machine, so I'm starting to study 68000. It looks like a lot of fun. With seventeen registers addressing 16 megabytes at 12 megaHertz or thereabouts, we should be able to do just about anything we want. I'll have a review next month of a new 68000 trainer board for your Apple, at about half the price of the existing 68000 boards.
To get to the point, how many of you good folks out there are interested in 68000? How many of you already know a little or a lot about it? Should we start a new newsletter about Macintosh? Should we devote a few pages of this one to it? Let us hear from you.
And another thing, how about C language? Several of you have mentioned that great August issue of Byte and expressed an interest in learning more about C. I know that I'm going to study up on it. There is a good C compiler available for the Apple, the Aztec C Compiler System from Manx Software. I'll have a review of it in the next month or two, and we may start carrying it for sale. Let me know if you're interested.
Here is what I think is a beautiful example of using nested recursive macros with the new .SE directive to calculate the addresses for a Spiral Screen Clear.
The macro SPIRAL calls, in order, LEFT, BOTTOM, RIGHT, and TOP to produce the code to handle each side of the screen. Each of those macros adjusts the appropriate X or Y coordinate and then calls GETADR to calculate the addresses and actually assemble the next instruction pair.
This program won't win any prizes for fast assembly: I timed it at almost 4 minutes. You could speed up the process by rewriting the BOTTOM and TOP macros. They really don't have to call GETADR for all the calculation, they only need to increment or decrement the addresses, but that destroys the symmetry of the original.
1000 .TF CLEAR 1010 .LIST OFF 1020 *-------------------------------- 1030 .MA SPIRAL 1040 >LEFT move left side up 1050 BOTLFT .SE BOTLFT-1 and move corner up 1060 >BOTTOM move bottom left 1070 BOTRGT .SE BOTRGT-1 and move corner left 1080 >RIGHT move right side down 1090 TOPRGT .SE TOPRGT+1 and move corner down 1100 >TOP move top right 1110 TOPLFT .SE TOPLFT+1 and move corner right 1120 .DO TOPLFT<13 done? 1130 >SPIRAL no, do it again 1140 .FIN 1150 .EM 1160 *-------------------------------- 1170 .MA GETADR 1180 ADRTO .SE ADRFRM 1190 BLOCK .SE Y.CORD/8 hi, mid, or low, 0-2 1200 BLK.AD .SE BLOCK*$28 block offset 1210 TEMP .SE BLOCK*8 1220 LINE .SE Y.CORD-TEMP line within block, 0-7 1230 LIN.AD .SE LINE*$80 line offset 1240 ADRFRM .SE $400+BLK.AD+LIN.AD+X.CORD 1250 LDA ADRFRM 1260 STA ADRTO 1270 .EM 1280 *-------------------------------- 1290 .MA LEFT 1300 Y.CORD .SE Y.CORD+1 down one step 1310 >GETADR 1320 .DO Y.CORD<BOTLFT done? 1330 >LEFT no, again 1340 .FIN 1350 .EM 1360 *-------------------------------- 1370 .MA BOTTOM 1380 X.CORD .SE X.CORD+1 right one step 1390 >GETADR 1400 .DO X.CORD<BOTRGT done? 1410 >BOTTOM no, again 1420 .FIN 1430 .EM 1440 *-------------------------------- 1450 .MA RIGHT 1460 Y.CORD .SE Y.CORD-1 up one step 1470 >GETADR 1480 .DO Y.CORD>TOPRGT done? 1490 >RIGHT no, again 1500 .FIN 1510 .EM 1520 *-------------------------------- 1530 .MA TOP 1540 X.CORD .SE X.CORD-1 left one step 1550 >GETADR 1560 .DO X.CORD>TOPLFT done? 1570 >TOP no, again 1580 .FIN 1590 .EM 1600 *-------------------------------- 1610 BOTLFT .SE 23 bottom left Y coord 1620 BOTRGT .SE 39 bottom right X coord 1630 TOPRGT .SE 0 top right Y coord 1640 TOPLFT .SE 1 top left X coord 1650 X.CORD .SE 0 start with upper 1660 Y.CORD .SE 0 left corner 1670 ADRFRM .SE $400 1680 *-------------------------------- 1690 LDX #960 do the loop 960 times 1700 LDY /960 1710 LDA #$A0 put space in center 1720 STA $5B4 1730 LOOP >SPIRAL do one spiral 1740 END DEX 1750 BNE .1 branch if not done 1760 DEY 1770 BPL .1 1780 JMP $3D0 exit to DOS 1790 .1 JMP LOOP go spiral again |
I have also produced a faster version of the program. This one uses self-modifying code to avoid shifting the already-cleared bytes on the screen. It's interesting to watch the self-modifying version accelerate as it moves fewer bytes each time through the loop. To produce the faster version, just replace the code from line 1680 on with this new code:
1680 POINTER .EQ 0 1690 *-------------------------------- 1700 LDY #0 no indexing 1710 LDA #END start pointer at end of code 1720 STA POINTER 1730 LDA /END 1740 STA POINTER+1 1750 .2 JSR LOOP do one step 1760 LDA #$AD restore LDA code 1770 STA (POINTER),Y 1780 *-------------------------------- 1790 LDA POINTER decrement pointer 1800 SEC by 6 1810 SBC #6 1820 STA POINTER 1830 BCS .1 1840 DEC POINTER+1 1850 .1 LDA #$60 insert RTS code 1860 STA (POINTER),Y 1870 *-------------------------------- 1880 LDA POINTER compare pointer 1890 CMP #LOOP to beginning of code 1900 BNE .2 1910 LDA POINTER+1 1920 SBC /LOOP 1930 BNE .2 branch if not yet done 1940 *-------------------------------- 1950 FIXUP LDA #$AD restore LDA 1960 STA LOOP at beginning 1970 LDA #$60 and RTS 1980 STA END at end 1990 JMP $3D0 and reenter DOS 2000 *-------------------------------- 2010 SAVE .DA #$A0 <space> to fill screen 2020 *-------------------------------- 2030 LOOP >SPIRAL 2040 LDA SAVE 2050 STA $5B4 2060 END RTS |
When Bob and I were first looking at Bruce Love's version of the Spiral Screen Clear, we got to wondering just how many lines actually were being processed by the assembler. With all those nested recursive macros, the total was bound to be in the thousands. Here's a little filter program I threw together to do a count:
0000- 1000 COUNT.LO .EQ 0 0001- 1010 COUNT.HI .EQ 1 0036- 1020 OUTHOOK .EQ $36 03EA- 1030 DOSHOOK .EQ $3EA 1040 *-------------------------------- 1050 .OR $300 1060 0300- A9 00 1070 LDA #0 0302- 85 00 1080 STA COUNT.LO zero the counters 0304- 85 01 1090 STA COUNT.HI 0306- A9 11 1100 LDA #LINE.COUNTER 0308- 85 36 1110 STA OUTHOOK direct output 030A- A9 03 1120 LDA /LINE.COUNTER to my routine 030C- 85 37 1130 STA OUTHOOK+1 030E- 4C EA 03 1140 JMP DOSHOOK 1150 *-------------------------------- 1160 LINE.COUNTER 0311- C9 8D 1170 CMP #$8D carriage return? 0313- D0 06 1180 BNE .1 no, exit 0315- E6 00 1190 INC COUNT.LO yes, count it 0317- D0 02 1200 BNE .1 0319- E6 01 1210 INC COUNT.HI 031B- 60 1220 .1 RTS
I assembled that code at $300, and then used these commands to set the PRT vector:
:$C083 C083 D009:4C 0 3 N C080
(For the motherboard versions of the S-C Assemblers, you only need to type :$1009:4C 0 3)
With that in place just load a source file, set .LIST ON, type PRT, and then type ASM. When the assembly is finished, type PR#0 to get the output back to the screen. Now you can type :$0.1 to look at the counters. You might also want to put a .LIST OFF line at the end of your program, so the count won't include the Symbol Table.
By the way, when the macros are expanded those 80 lines of Bruce's program produce 13,593 lines of code, or enough to fill over 200 pages of printout.
Frank Belanger sent me a copy of his new Hi-Res utility program, called SHAPEMAKER. I know, there are a lot of these on the market, such as Accu-Shapes and Apple Mechanic. Frank's is priced between those two, at $35, and look at all you get:
If these features interest you, write Frank at 4200 Avenue B, Austin, TX 78751. Or call (512) 451-6868.
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 $15 per year in the USA, sent Bulk Mail; add $3 for First Class postage in USA, Canada, and Mexico; add $13 postage for other countries. Back issues are available for $1.50 each (other countries add $1 per back issue for postage).
All material herein is copyrighted by S-C SOFTWARE, all rights reserved.
Unless otherwise indicated, all material herein is authored by Bob Sander-Cederlof.
(Apple is a registered trademark of Apple Computer, Inc.)