In This Issue...
New Goodies
We have several new products available this month. There are descriptions inside this issue of the new Cross Reference program for the S-C Macro Assembler, and the new book "Apple ][ Circuit Description". Also, the long-awaited RCA 1802 Cross Assembler is now ready, at $32.50.
Version 1.1 of the Macro Assembler is now ready to go! The upgrade from the current Version 1.0 will only cost you $12.50. That gets you //e, Videx, and STB 80-column support, 5 new directives and all the other new features described last month.
Yesterday afternoon I received two phone call in less than 30 minutes, both reporting that RAK-Ware's disassembler, DISASM, does not work on the Apple //e. The problem occurs when DISASM calls an odd entry into the monitor HOME routine. At several places in the routines to enter address information Bob Kovacs used $FC5A for a sort of combination VTAB and Clear-to-End-of- Page. Well, that won't work on a //e. The following patches change all the calls to $FC5A into $FC58, or the standard HOME routine. This will change the behavior of the program a little, making the screen clear between entries, rather than just tab down, but the program should now work.
84C:58 94D:58 A79:58 AD8:58 BBA:58 BFB:58
There must be at least a dozen products on the market now to speed up DOS 3.3: Diversi-DOS, David-DOS, The DOS Enhancer, QuickDOS, FastDOS, Hyper-DOS, et cetera. Some of these are unfortunately not compatible with the everyday programs we like to use, such as the S-C Assembler, ES-CAPE, or our favorite word processor. And it can be quite difficult sometimes to determine the degree of compatibity.
For the record, S&H Software's DOS Enhancer is completely compatible with the S-C Macro Assembler. David-DOS works well until you try to use the .TF directive.
Most of the speed-up systems only improve the speed of LOAD, BLOAD, RUN, BRUN, SAVE, and BSAVE. Some also speed up booting into the language card. And two (Diversi-DOS and David-DOS) speed up READing and WRITE-ing TEXT files, as well as offering a lot of minor enhancements in pursuit of more "user- friendliness".
It seems that the more the speed-up system does, the more compatibility problems you can expect. After all, to add a feature you do have to change some code. And many programs on the market expect the DOS image to be un-modified so they can jump into DOS subroutines in strange unexpected places and make their own custom patches to the DOS image.
Paul Schlyter (a subscriber in Sweden) sent me a small patch for DOS 3.3 early in April, 1982. Paul's patch speeds up only RUN, BRUN, LOAD and BLOAD, but it such a small patch that it will almost fit into the interstices (unused bytes) inside DOS. In fact, after I removed one bug and reorganized the code a little, I was able to fit it entirely within two unused areas: $BA69-BA95 and $BCDF-BCFF. [ Not true! See New Version of DOS -- Patcher's Beware" ] I believe the result is completely compatible with all the programs I use around here, except for the ones that use their own modified and protected DOS.
Paul's patch turns out to be functionally equivalent to the much longer patch proposed in HardCore Magazine's HyperDOS, but it leaves the INIT command intact.
I ran some timing tests:
LOAD 40 sectors standard 10 sec patched 3.5 sec BLOAD 37 sectors standard 11 sec patched 4 sec LOAD 132 sectors standard 32 seconds patched 7.5 seconds
I didn't try measuring times, but I suspect that SAVE and BSAVE may be just a little faster with this patch installed (during the read-after-write phase).
Since the S-C Assemblers use the LOAD command to process .IN directives, large assemblies with large included files will assemble about three times faster when you install this speed-up patch.
The patch is really rather simple. But before examining the patch, let's review the normal flow inside DOS for LOADing and BLOADing.
DOS is constructed in three layers: the outer layer accepts your commands from the keyboard or from your program. The inner layer, called RWTS, handles the intimate details of reading or writing a specified sector on a specified track. RWTS also does the raw disk initialization when you use the INIT command. The layer between commands and RWTS is called the File Manager (FM).
The command layer calls FM to open, close, rename, lock, unlock, verify, or delete a file; to print a catalog; to initialize a disk; or to position within a file. There are also four kinds of calls for reading and writing files, to read or write one byte or a range of bytes.
When you use the RUN or LOAD command, the command layer calls FM to read the first two bytes. These bytes contain the length of your program. For Integer BASIC or S-C Assembler source files, the length is subtracted from HIMEM to get a loading address. The loading address for Applesoft programs is found in $67,68. Then FM is called to read a range of bytes of that length, to be stored starting at the loading address just determined.
When you use the BRUN or BLOAD command, the first four bytes are read off the front of the file. The first two bytes are the loading address, and the next two are the length. (Of course, you can override the loading address with the "A" parameter after the file name.)
After winding our way through the front end of FM, we finally get to this subroutine (where the range is read):
1000 READ.RANGE AC96- 20 B5 B1 1010 JSR DECR.TEST.LENGTH AC99- 20 A8 AC 1020 JSR READ.BYTE AC9C- 48 1030 PHA SAVE THE BYTE AC9D- 20 A2 B1 1040 JSR GET.ADDRESS.INC ACA0- A0 00 1050 LDY #0 ACA2- 68 1060 PLA GET THE BYTE ACA3- 91 42 1070 STA ($42),Y STORE IN BUFFER ACA5- 4C 96 AC 1080 JMP READ.RANGE
The subroutine DECR.TEST.LENGTH breaks out of this loop when the range has been completely read. The READ.BYTE subroutine picks bytes out of the DOS buffer, and reads a sector into that buffer when the buffer is empty.
To understand the speed-up patch, break the reading process into three parts: the first sector, the last sector, and all the in-between sectors. We will let the loop shown above handle the first sector and possibly the last sector, and read the in-between sectors using a faster method. Short files with only one or two data sectors will not have any in-between sectors, and so there will be no improvement in speed.
First we need to read the rest of the first sector of the file. The first two or four bytes were already read to get address and length information. We can let the loop shown above do that job. But we need a way to break into the loop when it is our turn. Let's patch the JMP on the last line to jump to our patch.
Our patch will get control after the loop above has read and stored a byte of data. At that time our patch can look at the current file position in $B5E6; if $B5E6 is non-zero, then there are still bytes in the DOS buffer. As long as there are bytes in the DOS buffer, we will branch back to $AC96 and let FM handle the bytes in its normal way.
Once the first sector has been read and stored, a byte at a time, $B5E6 will have a zero value. Then our patch can look at the remaining length. If the remainging length is at least one whole sector, we can read it faster. If not, FM can read the last partial sector in its normal fashion.
To read a sector faster, we bypass the DOS buffer. We can temporarily patch the actual destination address where the sector must go into the RWTS call block. RWTS can put the entire sector directly into its final destination, rather than into the DOS buffer to be later moved by the rather slow loop above.
The extra time saved by eliminating the middle man will save an entire revolution of the drive to get the next sector (if it is in the same track, and they usually are). A 40 sector file laid out sequentially on three tracks will save 38 revolutions of the disk. The disk spins at 5 revolutions per second, so we will save a hair over 7 seconds. (If the file is not laid out sequentially, the savings will be less.)
The bigger the file, the bigger the percentage improvement. We can save 3 seconds per track. It normally takes FM about 18 revolutions to read a track; with our patch, a track can be read in about 3 revolutions. We save 15 revolutions or 3 seconds on each full track. That is, a full track can be read in .6 seconds instead of 3.6 seconds. The rest of the time required to read the file is spent moving the head from track to track, and reading the catalog and VTOC sectors.
If all 16 sectors of a track are to be read, and if the sectors were allocated the normal DOS 3.3 way, I think this is the way it happens with my patch installed:
F E D C B A 9 8 7 6 5 4 3 2 1 0 F 0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F 0
The bottom line of numbers shows the physical sector numbers. As you move across the page from left to right, you simulate the disk read head. It may take up to a full revolution of the disk before sector F appears, but once it does we proceed to pick off approximately every other sector as they come by. The top line of numbers shows the DOS 3.3 logical sector numbers. Logical sector E is actually physical sector 2, and so on. So it takes two full revolutions, plus two more sectors, to read all 16.
If you are trying to figure out where the rest of the time is used, keep in mind that DOS first reads the VTOC (track 17, sector 0); then the first catalog sector (track 17, sector 15); if the file specified is not in the first catalog sector, it reads another; and so on. If the file is far down in the catalog, it might have to read all 15 catalog sectors to find the file. Then the track/sector list is read; it is usually in sector 15 of the same track containing the first 15 sectors of data. On the other hand, as the disk fills up the sectors get splattered all over the disk.
Here is the patch code, arranged so that it squeezes into those two interstices I mentioned earlier:
1000 *-------------------------------- 1010 * S.FAST LOAD.1 1020 * 1030 * FAST "LOAD" AND "BLOAD" 1040 * 1050 * INSTALLED IN UNUSED AREAS IN DOS 3.3: 1060 * $BA69-$BA95 (45 BYTES FREE) 1070 * $BCDF-$BCFF (33 BYTES FREE) 1080 *-------------------------------- 1090 READ.RANGE .EQ $AC96 1100 READ.NEXT.SECTOR .EQ $B0B6 1110 END.OF.DATA.ERROR .EQ $B36F 1120 RANGE.LENGTH .EQ $B5C1,C2 1130 RANGE.ADDRESS .EQ $B5C3,C4 1140 BUFFER.ADDRESS .EQ $B5CB,CC 1150 SECTOR.COUNT .EQ $B5E4,E5 1160 BYTE.OFFSET .EQ $B5E6 1170 *-------------------------------- 1180 .OR $BA69 1190 .TF B.PATCH1 1200 1210 PATCH1 LDA BYTE.OFFSET LAST BYTE OF 1220 BNE GO.READ.RANGE A SECTOR? 1230 LDA RANGE.LENGTH+1 WHOLE SECTOR LEFT? 1240 BEQ GO.READ.RANGE NO. 1250 LDA BUFFER.ADDRESS SAVE BUFFER ADDRESS 1260 PHA 1270 LDA BUFFER.ADDRESS+1 1280 PHA 1290 LDA RANGE.ADDRESS READ DIRECTLY 1300 STA BUFFER.ADDRESS INTO RANGE 1310 LDA RANGE.ADDRESS+1 1320 STA BUFFER.ADDRESS+1 1330 1340 READ.LOOP 1350 JSR READ.NEXT.SECTOR 1360 BCS .1 1370 JMP PATCH2 1380 .1 JMP END.OF.DATA.ERROR 1390 1400 GO.READ.RANGE 1410 JMP READ.RANGE 1420 *-------------------------------- 1430 .OR $BCDF 1440 .TF B.PATCH2 1450 1460 PATCH2 INC SECTOR.COUNT 1470 BNE .1 1480 INC SECTOR.COUNT+1 1490 .1 INC RANGE.ADDRESS+1 NEXT PAGE 1500 INC BUFFER.ADDRESS+1 1510 DEC RANGE.LENGTH+1 1520 BNE .2 1530 PLA RESTORE BUFFER 1540 STA BUFFER.ADDRESS+1 1550 PLA 1560 STA BUFFER.ADDRESS 1570 JMP READ.RANGE ONE BYTE AT A TIME 1580 1590 .2 JMP READ.LOOP 1600 *-------------------------------- 1610 .LIF |
To install the patches, you need to BLOAD PATCH1 and BLOAD PATCH2. Then patch locations $ACA6-7 to 69 BA, to change the JMP READ.RANGE instruction to a JMP PATCH1. Note that you must BLOAD the patches before changing $ACA6-7. If you change $ACA6-7 first, the system will crash as soon as you try to execute a BLOAD.
Here is an Applesoft program (which you could append to your HELLO program) to poke the patches into DOS.
20000 REM INSTALL FAST DOS LOAD AND BLOAD PATCHES 20010 READ N: IF N = 0 THEN END 20020 READ A 20030 FOR I = 1 TO N: READ P: POKE A,P:A = A + 1: NEXT 20040 GOTO 20010 20100 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 20110 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 20120 DATA 2,44198,105,186 20130 DATA 0
Paul mentioned he was working on an equally simple patch to speed up SAVE and BSAVE, but I haven't heard any more from him on that subject.
Roger Johnson (Minnesota) called a week or so ago with a plea for an easy way to make program segments align themselves automatically on page boundaries. He was writing a system to be burned into EPROM and run on another computer; it would be easier to debug in the target machine if subroutines and data blocks began on even page boundaries. There was ample room, so the wasted bytes between routines didn't bother him.
Of course, the .OR directive in the S-C Macro Assembler can easily change the origin whenever you wish, but it also changes the target address (.TA directive) or closes any open target file (.TF directive). Therefore a different approach is required.
Bill Morgan and Mike Laumer described how to do this in these pages a few months back, using the .BS directive to reserve enough bytes to reach the next page boundary. But with the help of a simple macro, we can not only make it easier to make self-aligning code: we can also make it generate error messages if the origin we try to set involves backing up over a longer-than-expected predecessor.
Here is the macro definition, and a few lines demonstrating how to call the macro:
1000 .MA ORG 1010 .DO *>]1 1020 !!! ERROR: ORG ]1 RANGE CROSSED !!! 1030 .ELSE 1040 .BS ]1-* 1050 .FIN 1060 .EM 1070 *-------------------------------- 1080 .OR $800 1090 SAMPLE LDA $1234 1100 RTS 1110 >ORG $900 1120 STA $1234 1130 RTS 1140 >ORG $980 1150 DATA .DA #1,#2,#3
Line 1110 calls the ORG macro with a parameter of "$900". This means that everywhere you find "]1" in the macro definition, the assembler will see "$900". The conditional (.DO) on line 1010 will read ".DO *>$900". Since * equals $804 at this point, it is not greater than $900. Therefore the condition is false, and the lines following line 1010 will be skipped up to line 1030 where there is an ".ELSE". The lines after 1030 through the ".FIN" on line 1050 will be assembled. Line 1040 will be assembled as ".BS $900-*", which will bump the location up to $900.
Here's how the above example assembles:
1000 .MA ORG 1010 .DO *>]1 1020 !!! ERROR: ORG ]1 RANGE CROSSED !!! 1030 .ELSE 1040 .BS ]1-* 1050 .FIN 1060 .EM 1070 *-------------------------------- 1080 .OR $800 0800- AD 34 12 1090 SAMPLE LDA $1234 0803- 60 1100 RTS 0804- 1110 >ORG $900 0000> .DO *>$900 0000> .ELSE 0804- 0000> .BS $900-* 0000> .FIN 0900- 8D 34 12 1120 STA $1234 0903- 60 1130 RTS 0904- 1140 >ORG $980 0000> .DO *>$980 0000> .ELSE 0904- 0000> .BS $980-* 0000> .FIN 0980- 01 02 03 1150 DATA .DA #1,#2,#3
If we had written line 1110 as ">ORG $800" the condition on line 1010 would be true, causing line 1020 to be assembled. Line 1020 is illegal syntax for the assembler, so it will be listed after an error message. The "]1" will be filled in to make the line list like this:
*** BAD OPCODE ERROR 1110> !!! ERROR: ORG $800 RANGE CROSSED !!!
That will occur during pass one of the assembly, so no code will be generated. The error message will be the only output.
At last a Cross Reference Utility is available for the S-C Assembler that is fully compatible with the latest releases of the S-C Macro Assembler. It handles all the new directives, shows macro calls, and can even give an optional cross reference on the opcodes! It only takes a few seconds to cross reference even a huge file and begin the listing! It is even faster than the Macro Assembler in processing the source lines.
The Cross Reference Utility also can optionally print a paginated source file listing before printing the cross reference. That way you can be certain that you have a program listing with the same line numbers shown in the cross reference listing.
The price is reasonable: only $20.00 for the object code version and $50.00 for both source and object code. What other company sells source code to their utilities!
[ in printed copy, the following was an actual copy of a letter ]
VAGABONDO ENTERPRISES
1300 E. Algonquin - 3G
Schaumburg, IL 60195
(312) 397-8705
Over the past few years I have always enjoyed reading AAL and frequently found useful information. I appreciate this type of publication and hope that you will be able to continue its publication indefinitely. In my opinion, this is the "bedrock" support level for programming the Apple.
I have included a contribution for AAL that I have used with a statistical analysis system (never marketed). It's for "DATE" processing, (not "DATA"), and an overview is printed and enclosed herewith. The disk has both the source code and a "BRUNable" copy of the overview.
Again, thanks for a truly useful publication
My best,
[signed] Brooke (W. Boering)
PS. Bill Morgan's CATALOG ARRANGER was particularly revealing of this part of DOS. Please thank him for me if convenient.
1000 *-------------------------------- 1010 * DATE PROCESSING MODULES 1020 * BY BROOKE BOERING 1030 *-------------------------------- 1040 .OR $800 1050 *-------------------------------- 1060 * JUMP TABLE * 1070 JMP CONV1 MM/DD/YY -> STD FMT 1080 JMP CONV2 STD FMT -> MM/DD/YY 1090 JMP CONV3 STD FMT -> CENTURY 1100 * DAY & WEEKDAY CODE 1110 JMP CONV4 KICK STD FMT DATE UP 1120 * (FROM 1 TO 225 DAYS) 1130 *-------------------------------- 1140 * MONITOR EQUATES 1150 1160 COUT .EQ $FDED 1170 PRBYTE .EQ $FDDA 1180 *-------------------------------- 1190 * LOCAL EQUATES 1200 1210 LOC0 .EQ $40 (A3L) 1220 LOC1 .EQ $41 (A3H) 1230 LOC2 .EQ $42 (A5L) 1240 LOC3 .EQ $43 (A5H) 1250 ACL .EQ $50 1260 ACH .EQ $51 1270 XTNDL .EQ $52 1280 XTNDH .EQ $53 1290 AUXL .EQ $54 1300 AUXH .EQ $55 1310 ANSLO .EQ $50 1320 PLIER .EQ $51 1330 CAND .EQ $52 1340 SAVER .EQ $53 1350 SLASH .EQ $AF (/) 1360 *-------------------------------- 1370 * - - - - LOCAL WORKING - - - - * 1380 WKG .HS 0000000000000000 1390 BINYY .EQ WKG+0 1400 BINMM .EQ WKG+1 1410 BINDD .EQ WKG+2 1420 CENTURY.DAY.HI .EQ WKG+4 1430 CENTURY.DAY.LO .EQ WKG+5 1440 *-------------------------------- 1450 * USER ALTERABLE CONTROLS 1460 1470 * LOWEST ACCEPTABLE YEAR 1480 * DEFAULT= 75 1490 * HIGHEST ACCEPTABLE YEAR 1500 * DEFAULT= 84 1510 * DAY-OF-WEEK SKIP 1520 * DEFAULT= SUNDAY & SATURDAY 1530 *-------------------------------- 1540 * CONVERT EXTERNAL FORMAT 1550 * MM/DD/YY TO STANDARD INTERNAL 1560 * FORMAT; BITS YYYYYYYMMMMDDDDD 1570 * 1580 * ENTRY: RA= DATA ADDRESS-LO 1590 * RY= " " -HI 1600 * EXIT: CC= EQUAL IF OK 1610 * RA= YYYYYYYM BYTE 1620 * RX= MMMMDDDD BYTE 1630 * CC= NEQ IF ERROR 1635 .PG 1640 CONV1 1650 STA LOC2 SET INDIRECT ADDR 1660 STY LOC3 : 1670 LDA #0 INIT WKG 1680 STA BINMM 1690 STA BINDD 1700 STA BINYY 1710 *-- DO 'MM' 1720 JSR GET.DOUBLE 1730 BNE BADATE 1740 TAY ZERO? 1750 BEQ BADATE 1760 CMP #13 TOO HI? 1770 BCS BADATE 1780 STA BINMM ITS OK 1790 INC LOC2 KICK PAST '/' 1800 *-- DO 'DD' 1810 JSR GET.DOUBLE 1820 BNE BADATE 1830 TAY ZERO? 1840 BEQ BADATE 1850 LDX BINMM RX= INDEX TO LIST 1860 DEX 1870 CMP DAYS.COUNT,X 1880 BCC .3 G-A IF OK 1890 BEQ .3 G-A IF OK 1900 CMP #29 29TH (OF FEB)? 1910 BNE BADATE NO, ERR! 1920 STY BINYY YES, SET YY-FLAG 1930 * (ACCEPT TEMPORARILY) 1940 .3 1950 STY BINDD ITS OK (PROBABLY) 1960 INC LOC2 KICK PAST '/' 1970 *-- DO 'YY' 1980 JSR GET.DOUBLE 1990 BNE BADATE 2000 CMP OLDEST.YEAR 2010 BCC BADATE 2020 LDX BINYY RX= FEB 29TH FLAG 2030 STA BINYY = 0YYYYYYY 2040 BEQ .6 G-A IF NOT FEB 29 2050 AND #$03 LEAP YEAR? 2060 BNE BADATE ERR IF NOT LEAPYEAR 2070 *-- SET EXIT CONDITIONS 2080 .6 2090 LDA BINMM 2100 ASL 2110 ASL 2120 ASL 2130 ASL 2140 ASL 2150 ORA BINDD 2160 TAX RX= MMMDDDDD 2170 LDA BINYY 2180 ROL RA= YYYYYYYM 2190 LDY #0 EXIT OK 2200 RTS 2210 2220 BADATE 2230 LDY #$FF DATE ERROR EXIT 2240 RTS 2245 .PG 2250 ********************************* 2260 * S/R TO GET NEXT DOUBLE DIGIT 2270 * (MAINLY USED FOR DATE INPUT) 2280 * ENTRY: LOC2/3= DATA ADDRESS 2290 GET.DOUBLE 2300 LDY #0 2310 LDA (LOC2),Y 2320 TAX RX= TENS DIGIT 2330 INC LOC2 2340 LDA (LOC2),Y RA= UNITS DIGIT 2350 INC LOC2 2360 JSR ASC2BIN 2370 * (CC= ERROR STATUS; PASS BACK) 2380 RTS 2390 ********************************* 2400 * S/R TO CONVERT 2 ASCII DIGITS 2410 * TO SINGLE BINARY BYTE 2420 * 2430 * ENTRY: RA= UNITS ASCII DIGIT 2440 * RX= TENS ASCII DIGIT 2450 * 2460 * EXIT: CC= EQUAL IF OK 2470 * RA= BINARY EQUIV 2480 * CC= NEQ IF NON DIGIT 2490 ASC2BIN 2500 STA LOC1 (SAVE TEMP) 2510 TXA RA= TENS 2520 CMP #0 2530 BCC NOTNUM 2540 CMP #10 2550 BCS NOTNUM 2560 AND #$0F 2570 BEQ .4 2580 TAX 2590 LDA #0 2600 CLC 2610 .3 2620 ADC #10 2630 DEX 2640 BNE .3 2650 .4 2660 STA LOC0 2670 LDA LOC1 RA= UNITS 2680 CMP #0 2690 BCC NOTNUM 2700 CMP #10 2710 BCS NOTNUM 2720 AND #$0F 2730 CLC 2740 ADC LOC0 2750 LDX #0 SET EXIT= OK 2760 RTS 2770 2780 NOTNUM 2790 LDX #$FF 2800 RTS 2805 .PG 2810 *-------------------------------- 2820 * CONVERT STANDARD INTERNAL 2830 * DATE FORMAT, YYYYYYYMMMMDDDDD 2840 * TO EXTERNAL FORMAT MM/DD/YY. 2850 * 2860 * ENTRY: RA= HI BYTE (YYYYYYYM) 2870 * RX= LO BYTE (MMMDDDDD) 2880 * CV/CH PRESUMED PRESET 2890 CONV2 2900 *-- EXPLODE TO BINYY,BINMM,BINDD 2910 JSR EXPLODE.STANDARD.FORMAT 2920 LDA BINMM 2930 JSR DATE.MM PRINT MM 2940 LDA #SLASH PRINT '/' 2950 JSR COUT 2960 LDA BINDD 2970 JSR DATE.DD PRINT DD 2980 LDA #SLASH PRINT '/' 2990 JSR COUT 3000 LDA BINYY 3010 JSR DATE.YY PRINT YY 3020 RTS 3030 ********************************* 3040 * S/R TO CONVERT YY BYTE TO DECI- 3050 * MAL, THEN TO ASCII & DISPLAY. 3060 DATE.YY 3070 CMP #100 OVFLO PROTECT 3080 BCC .4 : 3090 LDA #99 : 3100 .4 3110 JMP DATE.DD GOTO COMMON 3120 ********************************* 3130 * S/R TO CONVERT MM BYTE TO DECI- 3140 * MAL, THEN TO ASCII & DISPLAY. 3150 DATE.MM 3160 CMP #12 OVFLO PROTECT 3170 BCC .4 : 3180 LDA #12 : 3190 .4 3200 JMP DATE.DD GOTO COMMON 3210 ********************************* 3220 * S/R TO CONVERT DD BYTE TO DECI- 3230 * MAL, THEN TO ASCII & DISPLAY. 3240 DATE.DD 3250 LDX #0 RX= 10'S CTR 3260 .2 3270 CMP #$A < 10 ? 3280 BCC .3 YES, JUMP OUT 3290 SEC 3300 SBC #$A MINUS 10 3310 INX KICK 10'S CTR 3320 BNE .2 LOOP BACK 3330 *JMP^^^ 3340 .3 3350 STA LOC0 SAVE TEMP 3360 TXA GET 10'S CTR 3370 ASL POSN HI 3380 ASL : 3390 ASL : 3400 ASL : 3410 ORA LOC0 'OR' TOGETHER 3420 JMP PRBYTE PRINT IT 3430 *RTS* 3435 .PG 3440 *-------------------------------- 3450 * CONVERT STANDARD FORMAT TO 3460 * CENTURY DAY & WEEKDAY CODE 3470 * 3480 * ENTRY: RA= YYYYYYYM 3490 * RX= MMMMDDDD 3500 * 3510 * EXIT: RA= CENTURY DAY (HI) 3520 * RX= CENTURY DAY (LO) 3530 * RY= WEEKDAY CODE 3540 * 1= MONDAY 3550 * 2= TUESDAY 3560 * 3= WEDNESDAY 3570 * 4= THURSDAY 3580 * 5= FRIDAY 3590 * 6= SATURDAY 3600 * 7= SUNDAY 3610 * 0= UNKNOWABLE 3620 CONV3 3630 *-- EXPLODE TO BINYY,BINMM,BINDD 3640 JSR EXPLODE.STANDARD.FORMAT 3650 *-- CALCULATE DAYS OF PRIOR YEARS 3660 LDY BINYY STORE 256 DAYS 3670 DEY : FOR EACH 3680 STY CENTURY.DAY.HI : PRIOR YEAR 3690 TYA STORE 1 DAY 3700 LSR : FOR EACH 3710 LSR : PRIOR 3720 STA CENTURY.DAY.LO : LEAP YEAR 3730 LDA #109 STORE 109 DAYS 3740 JSR MULTIPLY.8X8 : FOR EACH 3750 CLC A : PRIOR 3760 ADC CENTURY.DAY.LO : YEAR 3770 STA CENTURY.DAY.LO : 3780 TYA : 3790 ADC CENTURY.DAY.HI : 3800 STA CENTURY.DAY.HI : 3810 3820 *-- CALCULATE DAYS OF THIS YEAR 3830 LDY BINDD RY= DD 3840 TYA (IN CASE WAS JAN) 3850 LDX BINMM RX= MM 3860 DEX RX= MM-1 3870 BEQ .7 G-A IF WAS JAN 3880 CPX #1 3890 BEQ .3 G-A IF WAS FEB 3900 LDA BINYY (WAS MAR - DEC) 3910 AND #$03 LEAP YEAR? 3920 BNE .3 NO, G-A 3930 INY YES, KICK DAY CTR 3940 .3 3950 TYA RA= DD (OR DD+1) 3960 .4 3970 CLC ADD A MONTH'S DAYS 3980 ADC DAYS.COUNT-1,X : 3990 BCC .5 G-A IF > 255 DAYS 4000 INC CENTURY.DAY.HI 4010 .5 4020 DEX DECR CTR 4030 BNE .4 LOOP TIL DONE 4035 .PG 4040 .7 4050 *-- ADD THIS YEAR'S DAYS 4060 * TO PRIOR YEARS' DAYS 4070 *RA= DAYS THIS YEAR 4080 CLC 4090 ADC CENTURY.DAY.LO : 4100 STA CENTURY.DAY.LO : 4110 BCC .8 : 4120 INC CENTURY.DAY.HI : 4130 .8 4140 *-- CALCULATE WEEKDAY CODE 4150 TAX RX= CENTURY.DAY.LO 4160 LDA CENTURY.DAY.HI 4170 JSR GET.WEEKDAY 4180 * RY= WEEKDAY CODE 4190 RTS 4200 ********************************* 4210 * CALCULATE WEEKDAY CODE FROM 4220 * CENTURY DATE 4230 * 4240 * ENTRY: RA= CENTURY DATE-HI 4250 * RX= CENTURY DATE-LO 4260 * 4270 * EXIT: RA/RX= AS ON ENTRY 4280 * RY= WEEKDAY CODE 4290 * 1= MONDAY 4300 * 2= TUESDAY 4310 * 3= WEDNESDAY 4320 * 4= THURSDAY 4330 * 5= FRIDAY 4340 * 6= SATURDAY 4350 * 7= SUNDAY 4360 * 0= UNKNOWABLE 4370 GET.WEEKDAY 4380 STA ACH 4390 STX ACL 4400 PHA SAVE RA 4410 TXA SAVE RX 4420 PHA : 4430 LDA #0 4440 STA XTNDH SET DIV'D (HIHI) 4450 STA XTNDL SET DIV'D (LOLO) 4460 STA AUXH SET DIVISOR(LO) 4470 LDA #7 SET DIVISOR(HI) 4480 STA AUXL : 4490 LDY #8 SET FOR 8BIT DIVSR 4500 JSR DIVIDE.32X16 4510 LDA XTNDL 4520 CLC REMAINDER + WEEKDAY 4530 ADC #0 : OF 12/31/1900 4540 TAY (PRESET) 4550 SEC 4560 SBC #7 4570 BCC .4 G-A IF RY OK 4580 TAY (RESET) 4590 .4 4600 INY ADJ: ANS+1 = CODE 4610 PLA RESTORE RA/RX 4620 TXA : 4630 PLA : 4640 RTS 4645 .PG 4650 *-------------------------------- 4660 * ADD FROM 1 TO 225 DAYS TO 4670 * A GIVEN STD FORMAT DATE 4680 * 4690 * ENTRY: RA= YYYYYYYM 4700 * RX= MMMMDDDD 4710 * RY= # DAYS TO ADD 4720 * EXIT: RA/RX UPDATED 4730 CONV4 4740 *-- SAVE RY TO STACK 4750 STA LOC0 4760 TYA 4770 PHA 4780 LDA LOC0 4790 *-- EXPLODE TO BINYY,BINMM,BINDD 4800 JSR EXPLODE.STANDARD.FORMAT 4810 *-- INIT FOR LOOP 4820 PLA = # DAYS TO KICK 4830 CLC 4840 ADC BINDD RA= WKG CTR 4850 LDX BINMM RX= WKG MM 4860 .2 4870 * IN THIS LOOP: 4880 * RY= UTILITY REGISTER 4890 * RX= WKG MM TO BE INCREMENTED 4900 * RA= WKG CTR TO BE DECREMENTED 4910 * LOC3= WKG DAY COUNT FOR THE 4920 * CURRENT MM (IN RX) 4930 LDY DAYS.COUNT-1,X 4940 STY LOC3 = MM'S DAY COUNT 4950 CPX #2 IS MM FEB? 4960 BNE .4 NO, G-A 4970 *-- DO FEB 4980 PHA SAVE WKG CTR 4990 LDA BINYY 5000 AND #$03 LEAP YEAR? 5010 BNE .3 NO, G-A 5020 LDA #29 RESET DAY COUNT 5030 STA LOC3 : 5040 .3 5050 PLA RESTORE WKG CTR 5060 .4 5070 CMP LOC3 5080 BCC .7 G-A IF DONE 5090 BEQ .7 : (ALSO DONE) 5100 SEC WKG CTR MINUS 5110 SBC LOC3 : WKG DAY COUNT 5120 INX MM+1 5130 CPX #13 OVFLO? 5140 BCC .2 NO, LOOP BACK 5150 LDX #1 YES, SET MM= JAN 5160 INC BINYY : AND SET YY+1 5170 JMP .2 : AND LOOP BACK 5180 .7 5190 STA BINDD 5200 STX BINMM 5210 JSR IMPLODE.STANDARD.FORMAT 5220 RTS 5225 .PG 5230 ********************************* 5240 * S/R TO EXPLODE STD FORMAT TO 5250 * BINYY, BINMM & BINDD 5260 * ENTRY: RA= YYYYYYYM 5270 * RX= MMMMDDDD 5280 * EXIT: BINYY,BINMM,BINDD SET 5290 EXPLODE.STANDARD.FORMAT 5300 LSR RA= 0YYYYYYY CC=M 5310 STA BINYY 5320 TXA RA= MMMDDDDD 5330 PHA SAVE MMMDDDDD 5340 ROR RA= MMMMDDDD 5350 LSR 0MMMMDDD 5360 LSR 00MMMMDD 5370 LSR 000MMMMD 5380 LSR 0000MMMM 5390 STA BINMM 5400 PLA PULL MMMDDDDD 5410 AND #$1F RA= 000DDDDD 5420 STA BINDD 5430 RTS 5440 ********************************* 5450 * S/R TO IMPLODE BINYY, BINMM & 5460 * BINDD TO STD FORMAT 5470 * ENTRY: BINYY,BINMM,BINDD PRESET 5480 * EXIT: RA= YYYYYYYM 5490 * RX= MMMMDDDD 5500 IMPLODE.STANDARD.FORMAT 5510 LDA BINMM RA= 0000MMMM 5520 ASL 000MMMM0 5530 ASL 00MMMM00 5540 ASL 0MMMM000 5550 ASL MMMM0000 5560 ASL MMM00000 (CC=M) 5570 ORA BINDD MMMDDDDD 5580 TAX RX= MMMDDDDD (CC=M) 5590 LDA BINYY RA= 0YYYYYYY (CC=M) 5600 ROL RA= YYYYYYYM 5610 RTS 5620 ********************************* 5630 5640 OLDEST.YEAR 5650 .DA #75 5660 HIGHEST.YEAR 5670 .DA #84 5680 DAYS.COUNT 5690 .DA #31 (JAN) 5700 .DA #28 (FEB) 5710 .DA #31 (MAR) 5720 .DA #30 (APR) 5730 .DA #31 (MAY) 5740 .DA #30 (JUN) 5750 .DA #31 (JUL) 5760 .DA #31 (AUG) 5770 .DA #30 (SEP) 5780 .DA #31 (OCT) 5790 .DA #30 (NOV) 5800 .DA #31 (DEC) 5805 .PG 5810 ********************************* 5820 * 5830 * 8 X 8 MULTIPLY 5840 * 5850 * ENTRY: RY= MULTIPLCAND 5860 * RA= MULTIPLIER 5870 * 5880 * EXIT: RY= ANSWER-HI 5890 * RA= ANSWER-LO 5900 * 5910 * TIMING: 212 US - MAX 5920 * 180 US - MIN 5930 * 192 US - AVER 5940 * NOTE: KEEP CLOSE TO SGN8X8 5950 MULTIPLY.8X8 5960 STA PLIER SAVE (MULTI)PLIER 5970 STY CAND SAVE (MULTIPL)CAND 5980 LDA #0 RA= ANSWER-HI 5990 LDY #8 SET 8-BIT CTR 6000 MUL1 6010 LSR PLIER TEST NEXT BIT 6020 BCC MUL2 IF OFF, GO ROUND 6030 CLC 6040 ADC CAND IF ON, ADD 6050 MUL2 6060 ROR SHIFT ANSWER 1 BIT 6070 ROR ANSLO : 6080 DEY DECR POSITION CTR 6090 BNE MUL1 LOOP TIL DONE 8 BITS 6100 TAY RY= ANSWER-HI 6110 LDA ANSLO RA= ANSWER-LO 6120 RTS 6130 ********************************* 6140 * 6150 * 32 X 16 DIVIDE 6160 * 6170 * PRE-ENTRY: 6180 * DIVIDEND IN: 6190 * XTNDH,XTNDL,ACH,ACL 6200 * DIVISOR --> AUXL,AUXH 6210 * 6220 * EXIT: QUOTIENT -> ACL,ACH 6230 * REMAINDER -> XTNDL,XTNDH 6240 DIVIDE.32X16 6250 LDY #$10 INDEX FOR 16 BITS 6260 .2 6270 ASL ACL 6280 ROL ACH 6290 ROL XTNDL XTND/AUX 6300 ROL XTNDH : -> ACCUM 6310 SEC 6320 LDA XTNDL 6330 SBC AUXL MOD TO XTND. 6340 TAX 6350 LDA XTNDH 6360 SBC AUXH 6370 BCC .3 6380 STX XTNDL 6390 STA XTNDH 6400 INC ACL 6410 .3 6420 DEY 6430 BNE .2 6440 RTS 6450 ********************************* |
"Have you ever wanted to know the detailed circuit operation of your Apple ][ computer? Perhaps you were designing a peripheral or making a modification. Maybe you were repairing an Apple. You may have just been curious about how it works."
That's the first paragraph of a new book called The Apple ][ Circuit Description, by Winston D. Gayler. If the answer to that question is "yes", you need to look at this book. Circuit Description contains about 160 pages of text describing the operation of every component on the Apple's motherboard and keyboard. There are also 44 large fold-out pages of easy-to- read block diagrams, schematics, timing diagrams, and waveform drawings. The enlarged, readable schematics alone will be worth the price of the book to some users!
One of the first things Mr. Gayler handles is identifying the various revisions of the Apple ][, from the original Rev. 0 through last year's RFI treated motherboard, Rev. D. The body of the book covers that last version, while an appendix goes into the differences in all earlier revisions, and the diagrams show all revisions. The very latest thing, the Apple //e, is not mentioned, since that's a radical departure from all others.
The book is intended for engineers, technicians, students, and serious hobbyists. The descriptions, schematics, timing diagrams, and waveform drawings can be an invaluable help in designing peripherals and modifications, troubleshooting, studying practical circuit design, and just understanding how your Apple works.
Each chapter has two sections, Overview, and Detailed Circuit Description. You can cruise the Overview sections to get an idea of what's going on in each piece of your Apple, or you can sit down with the Detailed Circuit Description, the schematics, your Apple, and your TTL Data Book, and figure out each and every signal in the computer.
Here is a chapter-by-chapter summary:
1. Introduction and overview of the book.
2. Block-diagram discussion of the whole computer's structure, introducing concepts like "address multiplexer" and "video address generator". Apple's unique patented power supply is also covered here.
3. Clocks: the master oscillator, clock generator, and the horizontal portion of the video address generator. Clocks are especially important in the Apple due to their interplay with the video circuitry.
4. The vertical portion of the video address generator and the sync, blanking, and color burst signals.
5. RAM memory, the 4116's and their addressing, as well as the shared access scheme for the video memory.
6. The 6502 processor and its internal cycles, including read cycles, write cycles, RAM and ROM cycles, I/O and keyboard cycles, interrupts, and DMA (direct memory access).
7. On-board I/O devices, including cassette I/O, the game port, the speaker, and the current two-piece keyboard.
8. Video generator hardware, how it creates TEXT, LORES, and HIRES displays under software control.
Appendices:
A. Introduction to standard video signal techniques, for those of us who know even less about video than about digital.
B. Various revisions of the Apple motherboard. The main text of the book describes the RFI, Rev. D board. This appendix covers the differences in all earlier boards, as well as the old one-piece keyboard.
C. Schematics. Pages and pages of enlarged diagrams of all versions of the motherboard and keyboards.
In the Introduction, Gayler says that the reader should be familiar with TTL (gates, flip-flops, shift registers, and multiplexers) and should have a basic knowledge of micro- processor and microcomputer architecture. Well, I have a very basic knowledge of architectures, and almost no familiarity with TTL details. This book looks like it will be a great tool for learning about TTL, because I will be able to relate what the data books say about a chip to a knowledge of what that chip is doing in my very own Apple.
One thing I would like to see is a sort of cross-reference by motherboard coordinate. It would be nice to be able to ask the book "What is the function of that 74LS20 at location D2?" As it is, I had to look through several foldouts for a chip symbol labelled "D2". It is a NAND gate in "Fig. C-2. Clock Generator (all revisions)" Since it's part of a clock circuit, it must be covered in chapter 3. Several minutes of poking around in chapter 3 tells me that chip is part of one of the Apple's most unique features! Every 65th CPU cycle is slightly stretched (1117 us vs. 978 us) to maintain sync with the color signals, and D2 is responsible for triggering that stretch.
That last paragraph started out to describe a shortcoming of the book, and turned into yet another example of the kind of great information contained in The Apple ][ Circuit Description. If you're doing any hardware work with the Apple, or if you want to learn more about what's going on in there, you need this book.
The Apple ][ Circuit Description, by Winston D. Gayler. Published by Howard W. Sams. 8 1/2 by 11 comb binding. 172 pp. text, 44 fold-out diagrams. Shipping weight 3 lbs. List price is $22.95, our price will be $21 + shipping ($2 domestic, $12 overseas).
New Version of DOS -- Patchers BewareWhen Apple released the //e they apparently also slipped in a slightly revised version of DOS, called DOS 3.3e (or 3.3c. Reports differ.) The following information about the changes is from Tom Weishaar's DOStalk column in the April issue of Softalk. The boot routine now throws a couple of new soft switches ($C00C and $C00E) and stores $FF in location $4FB. These steps turn off the //e's 80-column mode during boot-up. A routine at $B331 that calculates position in a random access file is now simplified. Now for the biggie: Another APPEND fix! (attempted) According to Weishaar, they eliminated a bug that occurred maybe once in 10,000 tries by introducing a new bug that bites once every 256 calls. Tom says that the most reliable method is to use the old DOS 3.3 and POKE -18851,0 before each APPEND. The most significant thing about the APPEND change is where they put the patch: at $BA69! That used to be empty space and a popular place to install patches. No more! As a matter of fact, Bob's Fast Load patch in this issue goes into that area, and therefore should not be used with DOS 3.3e. This means that //e users should be especially careful about installing published patches into DOS 3.3e, and all of us should quit using $BA69-BA95 for patches that will be distributed. |
My favorite new feature in Version 1.1 of the S-C Macro Assembler is the .PH directive. When Bob first described the new directive to me, I didn't quite see how to use it. Then he showed me a program like this one, and now I don't see how I did without it!
The directive .PH <expr> in an assembly causes the origin to be reset to <expr>, but the code continues to be stored in successive bytes of the same area as before. The result is much like the following lines all rolled into one:
2000 LABEL 2010 .OR SOMEWHERE.ELSE 2020 .TA LABEL
The difference is that the above lines would close an open Target File, whereas .PH SOMEWHERE.ELSE continues to direct code into the same file. The end of an offset block is marked with a .EP directive, that restores the origin to match the target address.
With this feature is so easy to assemble one program to create some patches and move them into place, all in one step. Anyway, here's the general purpose PATCHER, with some dummy code to show it off.
1000 *SAVE S.PATCHER 1010 *-------------------------------- 1020 PNTR .EQ $00,01 1030 PATCH .EQ $02,03 1040 *-------------------------------- 1050 .OR $300 1060 .TF B.PATCHER 1070 *-------------------------------- 1080 PATCHER 1090 LDA #PATCHES-1 1100 STA PNTR 1110 LDA /PATCHES-1 1120 STA PNTR+1 1130 LDY #0 1140 1150 .1 JSR GET.BYTE LENGTH OF NEXT PATCH 1160 BEQ .4 FINISHED 1170 TAX SAVE LENGTH IN X 1180 JSR GET.BYTE ADDRESS OF PATCH 1190 STA PATCH 1200 JSR GET.BYTE 1210 STA PATCH+1 1220 1230 .2 JSR GET.BYTE 1240 STA (PATCH),Y 1250 INC PATCH 1260 BNE .3 1270 INC PATCH+1 1280 .3 DEX 1290 BNE .2 1300 BEQ .1 ...ALWAYS 1310 1320 .4 RTS 1330 *-------------------------------- 1340 GET.BYTE 1350 INC PNTR 1360 BNE .1 1370 INC PNTR+1 1380 .1 LDA (PNTR),Y 1390 RTS 1400 *-------------------------------- 1410 P1.ORIGIN .EQ $1000 1420 P2.ORIGIN .EQ $2000 1430 P3.ORIGIN .EQ $3000 1440 1450 * OTHER .EQUATES HERE 1460 1470 *-------------------------------- 1480 PATCHES 1490 1500 .DA #P1.LENGTH,P1.ORIGIN 1510 .PH P1.ORIGIN 1520 1530 PATCH1 1540 * PATCH1 CODE HERE 1550 JMP PATCH2 1560 1570 P1.LENGTH .EQ *-PATCH1 1580 .EP 1590 *-------------------------------- 1600 .DA #P2.LENGTH,P2.ORIGIN 1610 .PH P2.ORIGIN 1620 1630 PATCH2 1640 * PATCH2 CODE HERE 1650 JMP PATCH3 1660 1670 P2.LENGTH .EQ *-PATCH2 1680 .EP 1690 *-------------------------------- 1700 .DA #P3.LENGTH,P3.ORIGIN 1710 .PH P3.ORIGIN 1720 1730 PATCH3 1740 * PATCH3 CODE HERE 1750 JMP PATCH1 1760 1770 P3.LENGTH .EQ *-PATCH3 1780 .EP 1790 *-------------------------------- 1800 .DA #0 END OF PATCHES 1810 *-------------------------------- 1820 .DO *>$3D0 1830 !!! PATCHER IS TOO BIG !!! 1840 .FIN |
Notice that the object code columns show the bytes to be all over pages 3, 10, 20, and 30. The labels in the Symbol Table show the same thing. But, if you look around in memory, all this is in page 3. Once you type $300G, the JMP instructions will be moved to their true destinations.
Bob's DOS Fast Load patches elsewhere in this issue are an ideal example of how to use PATCHER. Here's all it takes:
1> Make the following changes to lines 1410-1430 of PATCHER:
1410 P1.ORIGIN .EQ $BA69 1420 P2.ORIGIN .EQ $BCDF 1430 P3.ORIGIN .EQ $ACAF
2> Substitute Lines 1090-1160 of Fast Load for Line 1450 of PATCHER.
3> Substitute Lines 1210-1410 of Fast Load for Lines 1530-1550 of PATCHER.
4> Substitute Lines 1460-1590 of Fast Load for Lines 1630-1650 of PATCHER.
5> And substitute the following line for Lines 1740-1750 of PATCHER:
.DA PATCH1
Now you have a BRUNnable program which will quickly install the Fast Load patches into DOS. And if you want to add other DOS patches to the same program, just tack them in between lines 1790 & 1800.
If you want to patch something running in a RAM card, like the Macro Assembler, you just need to add the following lines:
1082 LDA $C083 1084 LDA $C083 1315 .4 LDA $C080 1320 RTS
And that's how I expect to handle patches from now on. Hope you find it useful!
Advanced Peripheral Enterprises has introduced their PRAWM board, and is advertising elsewhere in this issue of AAL.
The PRAWM board contains from 2K to 8K of EEPROM. Data or programs can be written into the memory on the card, just as though it were RAM. Yet the memory is non-volatile, as in ROM, PROM, or EPROM. If you turn of your Apple, remove the card, ship it around the world...when you plug it back in the bytes will still be there!
EEPROM stands for "Electrically Eraseable PROM"; circuitry on the card allows you to individually write any bytes you wish, without erasing the rest of the memory. You do not need a separate EPROM programmer and ultraviolet EPROM eraser. There are no batteries either. The card is priced about the same as an EPROM card, but you save a lot of money on accessories. You will also save a lot of time, since you don't have to erase for 30-60 minutes, program chips for 5-20 minutes, and plug and unplug countless times. (You can program the entire 8K on a fully loaded PRAWM board in less than 25 seconds!)
The PRAWM card contains from 1 to 4 EEPROM chips, providing from 2K to 8K bytes. Each chip maps into the address space from $C800-$CFFF, and is accessed by switching in one chip at a time. On-board firmware makes it easy to move blocks of data between any chip and RAM.
By installing a jumper strap, you can even have the program stored in the first 2K chip automatically start up when you turn on your Apple, before or instead of booting a floppy. Just think of the possibilities: set up special commands, execute security procedures, power fail recovery, "boot" a mini-DOS of your own creation from PRAWM, eliminate the need for disk drives in turn-key monitoring applications...! Other strap options allow you to write-protect the board and to disable the $CFFF de-select function.
If you do a lot of development work involving EPROMs now, I think this card would be a big help. See Advanced Peripheral Enterprises' ad for price and ordering information.
The FLASH! Integer Basic Compiler was recently reviewed by PEELINGS magazine and received an A+. It is currently the highest rated Integer compiler (the competition is rated only A). The price? Just $79.00 ($70 less than the competition)!
We recently had one customer give us a great compliment on the S-C Word Processor. He has given up on WORDSTAR! He found that the S-C Word Processor can read and write large text files 20 times faster than WORDSTAR and that scrolling was much quicker. He can be in and out of the S-C Word Processor before WORDSTAR even lets him type a single key. The S-C Word Processor is also much less expensive than WORDSTAR and you don't have to buy a Z-80 card!
His only desire was to have an 80 column version of the Word Processor. However, that wouldn't be nearly so fast since SCWP re-writes the screen on every keystroke. I have noticed also that the 40 column display never causes me eye strain, but all the 80 column displays do.
Laumer Research has recently introduced a new utility for the S-C Macro Assembler. This month seems to be the time for new utilities.
The Full Screen Editor is used with a language card and a 48K Apple. It runs in the spare 4K memory bank of a language card and is entered from the S-C Macro Assembler by typing "/" optionally followed by a line number. The neat thing is that all of the assembler regular editing commands COPY, REPlace, EDIt, FINd etc. are also availiable at the same time. It is almost a Macro Assembler Upgrade by itself.
It functions similar to the EDIt command in the macro assembler except that you can move forward and backward though the lines with cursor moves or move with paging keys a whole screen at a time. One intresting new edit command is control-C which can copy characters from the line above the cursor to the next tab stop of the current line. What a handy feature! How many times have you had to comment a routine that had no comments in it? With a control-W key a new left margin can be set at the comment area so every time you type the RETURN key you are all set to type the next comment line. This makes commenting a routine is as easy as eating apple pie!
The Screen Editor really cleans up a display because long lines are not wrapped arround on the display. Instead they are shown in a "window" on the display and the window can be moved up and down though a file and left or right to view long lines. As you type over the right side of the screen the "window" tracks over to always keep the cursor in the "window" of the screen.
It is very fast! Flipping though the pages of a source file to the routine you want to look at is just a few taps of a key. I hardly ever use the LISt command any more because the full screen editor is so easy to use: "/2400" for example will enter the editor and move to line 2400 at the top of the display.
For my own use I have made a Macro Assembler diskette that I boot on when I need the assembler. It loads up the Assembler and Screen Editor at the same time and applies several of the more useful patches published in the Apple Assembly Line for the Macro Assembler. An EXEC file is provided on the program diskette which can load the screen editor in to the langauge card from the assembler.
One of the most unusual features of the Screen Editor is that it comes with a SYSGEN program to help you create different customized versions of the screen editor for STB80 or VIDEX 80 column cards or the regular 40 column Apple II display. This keeps a user from performing a complicated series of BLOADs, POKEs and BSAVEs to modify the tab tables, screen width, margin settings and scroll values.
Some of the parameter settings are settable within the editor while you are editing like tab stops and the left margin. Others however are not accessable without re-running the Applesoft SYSGEN program and thats somewhat of a problem. I can't complain too much though because the source code comes with it and I can make it do anything extra that I want it to.
The Screen Editor can be used with the S-C Macro Cross Assemblers except for the 68000 version. Only the Z-80 cross assembler requires a slight adjustment to the small 20 byte patch for the "/" command. Provided with the program diskette is a tidy 9 page manual that describes the Screen Editor features and the patches to the assembler required.
We only have one machine here at S-C Software with an 80 column board but we use the Screen Editor mostly with the regular Apple II driver module. Bob S-C is still holding out on using it but the rest of us counted how many times we typed the LISt command and decided to screen edit instead. The Full Screen editor does for S-C Macro Assembler programmers what ES-CAPE does for Applesoft programmers. They both make my job a lot easier!
The price for this little jem is $49.00 for both source and object code.
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.)