In This Issue...
Current Advertising Rates
Sorry, it is going up again. For the October 1982 issue the price will be $75 for a full page, $40 for a half page. To be included, I must receive your camera-ready copy by September 20th.
What if you move?
We mail the Apple Assembly Line by bulk mail, unless you have paid for First Class or Overseas postage. If you move, the post office will NOT forward AAL to your new address. Please let us know your new address as soon as you find out what it will be, so you will not miss a single issue!
Quarterly Disks
As you no doubt know, every three months we gather all the source code printed during the quarter on one disk. You can save countless hours of typing and proofreading for only $15 per quarter. Some have elected to establish a standing order with their credit card, or even to prepay for a year at a time.
New Products
ES-CAPE: For really painless Applesoft programming, you need a complete line editor, global search and replace, automatic line numbers, and keyboard macros. At least. ES-CAPE gives you all these and more!
The retail price is $60, but AAL subscribers can get it for only $40 until the end of September. Hurry!
We wrote a nice little reference manual of about 22 pages, but ES-CAPE is so easy to use and remember that you won't need the book very long!
If you already purchased AED II (the earlier version of this editor), Bill Linn has an upgrade offer: Send him your disk plus $10, and you will get the new versions (both regular and language card), the manual, and the reference card.
68000 Macro Cross Assembler: Not content with producing only three cross assemblers based on the S-C Macro Assembler, Bobby Deen has now completed the biggest one of all! This one costs $50, and allows you to assemble Motorola 68000 source programs in your Apple, with all the friendly features of the S-C package.
SYNASSEMBLER: Synapse Software has just started marketing a conversion of the S-C Assembler II Version 4.0 for the Atari 800 or 400. You need 48K RAM and at least one disk drive. The conversion was done by Steve Hales, of Livermore, California. He added global replace and copy commands, so this version falls somewhere between the Apple version 4.0 and the new Macro version. It assembles at about 6500 lines per minute, which is from 50 to over 100 times faster than the Atari ASM/ED program.
Since the Atari does not have nice monitor commands built-in, like the Apple does, Steve added a complete set of monitor commands to SYNASSEMBLER. They look exactly like the Apple monitor commands, except that he added some new ones to allow reading and writing a range of disk sectors, delete the tape I/O commands, and included the old Step and Trace commands which were in Apples before the Autostart ROM.
The price is only $49.95 on disk. A ROM version is available by special order for $89.95. I will carry these, if you want to order from me.
Of all the Apple assemblers on the market, it seems that no two have exactly the same list of assembler directives. Directives, also called "pseudo-ops", are used to control the assembly process and to define data in your programs. When you see a listing of an assembly language program in a magazine, or in this newsletter, or in a book on 6502 programming, you may have to translate the directives to fit the assembler you own.
All directives in the S-C Macro Assembler begin with a period. This helps to distinguish them visually from 6502 and SWEET-16 opcodes. This same convention is used by Carl Moser's (Eastern House Software) MAE assembler, by the MOS Technology and Rockwell assemblers, and some others. Most other assemblers use 3- or 4-character mnemonics beginning with a letter. Which combination of letters cause the assembler to perform a particular function is not standardized at all, but there are enough similarities to make programs readable once you learn the general techniques.
What follows is an alphabetical listing of all the directives I have encountered in various manuals and magazine-published programs. The assemblers represented are coded like this:
B = Big Mac SC= S-C Macro Assembler K = DOS Tool Kit T = TED II L = Lisa W = Weller's Assembler M = Merlin
In each case I have given a brief description of the directive, and tried to show how to do the same thing in the S-C Macro Assembler. I suggest looking up the S-C directives in the reference manual if you are not sure exactly how to use them.
ADR ADdRess L Stores the expression as an address, low-order byte first. SC: Use .DA directive ASC ASCii string definition L K T B M SC: Use .AS or .AT directives. AST ASTerisks T B M Prints the number of asterisks specified on the listing. Used to save space in the source file. SC: Not needed, because SC compresses repeated characters automatically. BLK BLinKing characters L Generates a string of characters in Apple's FLASH code. SC: Not available, but a combination of .AS and .HS directives will do the job. BYT BYTe data L Define data value, storing low-order byte only. SC: Use .DA with "#" before value. CHK CHecKsum B M SC: Not available CHN CHaiN to next source K SC: Use .IN directive. CHR Set CHaR for REP directive K Used to create fancy comments with repeated strings; saves space in source file. SC: Not necessary, because SC compresses repeated characters automatically. .DA DAta definition L SC Apparently Randy borrowed this one from me. (See the reviews he wrote in Call APPLE some time ago.) DA Define Address T B M Defines a 16-bit value with low-byte first. SC: Use .DA directive. DATA DATA definition W Defines numeric and ASCII data bytes SC: Use .DA directive, preceding each value with "#". DB Data Byte T Defines a data value, only using the low byte of the expression. SC: Use .DA directive with "#" before the expression. DBL DouBLe precision data W Defines 16-bit data values. SC: Use .DA directive. DBY Double BYte data L Generates a 16-bit value and stores it high-byte first. SC: Not directly available, but use .DA as follows: .DA /expression,#expression DCI Define Characters Immed L K T B M Stores string with sign bit of last byte opposite that of the rest of the bytes. SC: Use .AT directive. DCM DOS CoMmand L Issue a DOS command during assembly. Usually used to BSAVE a section of the generated object code. SC: Use .TF directive DDB Define Double Byte K B M Defines a 16-bit value which is stored with the high-byte first. SC: Not directly available, but use .DA as follows: .DA /expression,#expression DEND Dummy END K Marks end of a dummy section (see DSECT). SC: Not available DFB DeFine Byte K B M Defines one or more bytes. SC: Use .DA, preceding each expression with "#". DFC DeFine Character L (old version) Data definition, byte expression list SC: Use .DA directive, preceding each expression with "#". DFS DeFine Storage L Reserve a block of bytes. An optional second operand will cause the reserved bytes to be set to the specified value. SC: Use .BS directive. No option to set the reserved bytes to a specified value. DO DO K B M Start a conditional assembly block. SC: Use .DO directive. DPH DePHase L Terminates a PHS directive. SC: Not available. DS Data Storage T K B M Reserve a block of bytes. SC: Use .BS directive. DSC Data SeCtion L (old version) Not sure what this was for. DSECT Dummy SECTion K Starts a block in which the object code bytes are not written on the output file. SC: Not available. DW Define Word K T Defines a 16-bit value, with the low-byte stored first. SC: Use .DA directive. .EL ELse L SC For conditional assembly. ELSE ELSE K B M For conditional assembly, toggles the truth value from the DO directive. SC: Use .ELSE directive. END END of program L T B M W Most assemblers REQUIRE an "END" directive at the end of the source code. S-C allows it but does not require it. SC: Use .EN directive. ENTRY ENTRY K Indicates a symbol is to be made reference-able from other separately-assembled modules. To be used by a linking loader program, which Apple does not provide. SC: Not available. EOM End Of Macro B M Marks end of a macro definition. SC: Use .EM directive. EPZ Equate Page Zero L label EPZ expression Defines the label to have the value of the expression, which must be from $00 to $FF. When EPZ-defined labels are used in address fields, zero-page addressing mode will be used whenever possible. SC: Use .EQ directive. SC automatically uses page-zero mode whenever possible. EQU EQUate L T K B M W label EQU expression Defines the label to have the value of the expression during the assembly process. SC: Use .EQ directive. ESP End ScratchPad W Works with SPD to bracket a data section. SC: Not needed. EXP EXPansion of macros B M Controls whether macro expansion code is printed or not on the output listing. SC: Use .LIST directive. EXTRN EXTeRNal K Indicates that a label is externally defined. To be used with a linking loader program, which Apple does not provide. SC: Not available. .FI end of conditional L SC FIN end of conditional K B M SC: Use .FIN directive. FLS FLaSH B M Define a string in flashing mode. SC: Not available, but a combination of .AS and .HS directives will do the job. GEN GENerate code listing L Turns on listing of all object code bytes. SC: Not available, object code listing is always on. HBY High BYte L Define one-byte data value, storing only the high-byte of an expressions value. SC: Use .DA directive, writing "/" before the value. HEX HEXadecimal data L T B M label HEX hexstring SC: Use .HS directive. ICL InCLude L Really is a CHAIN to next source file. SC: Use .IN directive. .IF conditional assembly L SC: Use .DO directive. INV INVerted characters L B M Generates a string of characters in Apple's INVERSE screen code. SC: Not available, but you can convert to hexadecimal and use .HS directive. LET label reassignment L Same as EQU, except label can be redefined during assembly. SC: Not available. LST LiST option L T K B M Turn assembly listing on or off. SC: Use .LIST directive. MAC MACro definition B M Start a macro definition. SC: Use .MA directive. MSB Most Signficant Bit K Controls whether the ASC directive generates bytes with the first bit set or clear. SC: Use .AS or .AT directives with or without the "-" before the first delimiter to indicate the MSB value. NLS No List option L Turn assembly listing off. SC: Use .LIST OFF directive. NOG NO Generate L Turns off listing of all but first three bytes of any particular source line. SC: Not available. OBJ OBJect address L T B M Set actual memory address for assembled object code to be stored in. SC: Use .TA directive. ORG ORiGin L T K B M Set memory address program will execute at. SC: Use .OR directive. PAG PAGe eject on listing L T B M Sends control-L to listing device. SC: Use .PG directive. PAGE PAGE eject on listing K Sends control-L to listing device. SC: Use .PG directive. !np PAU PAUse and force error L B M SC: Not available. PHS PHaSe L Allows setting ORG without changing OBJ. Terminated with DPH. SC: Not available. PMC Present MaCro B M Opcode to call a macro. SC: Not needed, macros are called by their own names. PR# Select printer slot T SC: Select before assembly begins using DOS "PR#slot" command, or SC "PRT" command. REL RELocatable object K Causes assembler to generate a relocation dictionary at the end of the object file, for use by Apple's relocating loader. SC: Not available. REM REMark W Used to indicate a comment line. SC: Use "*" in first column of label field. REP REPeated character K Generates a string of repetitions of the current CHR value on the output listing. Used to save space in the source file. SC: Not needed, because SC automatically compresses repeated characters. SAV SAVe object code B M SC: Use .TF directive. SBTL SuBTitLe K Provides a title line for the top of each page of the output listing. SC: Use .TI directive. SKP SKiP lines K B M Leaves a specified number of blank lines in the output listing. SC: Not available. SPD ScratchPaD W Works with ESP to bracket a data section. SC: Not needed. STR STRing L Similar to Lisa's ASC except the first byte output is the length of the string. SC: labela .DA #labelb .AS /string/ labelb .EQ *-labela-1 SYM SYMbols T Produces a symbol cross-reference table at end of assembly. SC: Not available, but can use Rak-Ware's XREF utility program. TITL TITLe TTL TiTLe L Generates title line at top of each page of listing. SC: Use .TI directive. TR TRuncate object listing B M Limit listing of object code to 3 bytes per source line. SC: Not available. USR USeR directive L An extra entry in the directive table for the user to use as he sees fit. SC: Use .US directive. ; comment indicator L SC: If ";" was in first column, use "*" instead. If in later column, no special character is needed. = equate B M others If written with label on left, this is the same as EQU and .EQ directives. If written with "*" on the left, it is the same as ORG and .OR directives. <<< B M Alternate syntax for EOM. SC: Use .EM directive. >>> B M Alternate syntax for PMC. SC: Not needed, because macros are called by their own names.
Directives in Roger Wagner's Book
If you have been trying to learn using the S-C Assembler with Roger's book "Assembly Lines: The Book", you may have been frustrated by his use of several assembler directives. He discusses directives on pages 16-18, and 55.
On page 16, the first example of the use of directives has two errors. Lines 6 and 7 are written:
6 OBJ EQU $300 7 ORG EQU $300
But they should be:
6 OBJ $300 7 ORG $300
That is, OBJ and ORG are directives, not labels. The top two lines on page 21 are also incorrect, in that the ORG and OBJ directives were typeset to look like labels; they should be moved over to the opcode column, and the "$300" values to the operand column.
In all, Roger uses only five directives in his book: OBJ, ORG, EQU, ASC, and HEX. To use his programs in the S-C assembler, change:
From To ---------------- ---------------- label EQU value label .EQ value label HEX hexdigits label .HS hexdigits HEX hexdigits .HS hexdigits label ASC "characters" label .AS -"characters" ASC "characters" .AS -"characters" OBJ $300 or $302 omit this line ORG $300 or $302 .OR $300 or $302
Note that the normal translation of "OBJ" is ".TA"; however, when the address is the same as the ORG/.OR address, it is not necessary to use OBJ/.TA. Furthermore, in the S-C Assemblers you must put the ".OR" line BEFORE the ".TA" line. In Roger's examples these two lines are reversed.
In recent issues of AAL there have been a variety of routines to produce relocatable code. The BSR, BRA and LEAX opcodes in the June issue and the run-anywhere subroutine calls in the July issue are two examples.
However, in making some of my code relocatable, I encountered a new problem with routines that interface with Applesoft programs through the & command. The problem is that the routine doesn't know what address to place in the & jump vector because that address may change with each run.
A rather inelegant solution is to derive the address from Applesoft's pointers, then POKE it into the & vector before calling it. What I wanted was a method to determine the correct address from within the code itself, in much the same way that a non-relocatable program sets up the vector:
1000 LDA #$4C 1010 STA AMPER.VECTOR 1020 LDA #START 1030 STA AMPER.VECTOR+1 1040 LDA /START 1050 STA AMPER.VECTOR+2 1060 * 1070 START ... |
I have written a short routine which will handle the initialization at the beginning of relocatable programs, as long as the program's entry point immediately follows, as in the sample program listed below.
The routine works by first jumping to the subroutine at $FF58, which is simply an RTS instruction. As Bob explained in the July AAL, this places the return address on the stack and then pops it back off again. The return address can then be found by reading the first two open bytes below the stack. The TSX instruction in line 1100 loads the offset to those two bytes into the X-register. Lines 1110-1130 load the bytes into the A- and Y-registers.
Now we have the address of the third byte of the JSR RETURN instruction - the MSB in Y and the LSB in A. What we need is the address of the program's entry point, which corresponds to the label START. To get that address, we must add in the length of the rest of the SETUP routine, that is, the difference between the address at START and the address in the Y- and A-registers.
This is handled in lines 1140-1170. Line 1150 adds the offset ($1B for this particular routine) to the low byte of the base address. The extra 1 in the ADC intruction is necessary because the address in Y and A is one less than the actual return address (corresponding to .1). Lines 1160-1170 check for a carry and adjust the high byte if necessary. The entry point address is then saved in the ampersand vector at $3F5-$3F7.
1000 *-------------------------------- 1010 STACK .EQ $100 1020 AMPER.VECTOR .EQ $3F5 1030 RETURN .EQ $FF58 1040 HOME .EQ $FC58 1050 *-------------------------------- 1060 .OR $300 1070 .TF B.AMPEXAMPLE 1080 *-------------------------------- 1090 SETUP JSR RETURN PUT CURRENT ADDR ON STACK 1100 .1 TSX GET STACK POINTER FOR OFFSET 1110 LDY STACK,X MSB OF ADDR ON STACK 1120 DEX 1130 LDA STACK,X LSB 1140 CLC 1150 ADC #START-.1+1 OFFSET TO ENTRY POINT 1160 BCC .2 1170 INY (Y) IS HI BYTE 1180 .2 STA AMPER.VECTOR+1 LSB OF ENTRY ADDRESS 1190 STY AMPER.VECTOR+2 MSB 1200 LDA #$4C JMP OPCODE 1210 STA AMPER.VECTOR 1220 RTS 1230 *-------------------------------- 1240 START JSR HOME CLEAR SCREEN 1250 NOP DO WHATEVER 1260 NOP YOU LIKE 1270 RTS |
The same principle can be used to set up the monitor's control-Y vector at $3F8-$3FA. As a matter of fact, I usually use a macro with conditional assembly to set up whichever vector I need. Here's the macro:
1000 .MA VECTOR 1010 JSR $FF58 1020 :1 TSX 1030 LDY $100,X 1040 DEX 1050 LDA $100,X 1060 CLC 1070 ADC #:3-:1+1 1080 BCC :2 1090 INY 1100 :2 .DO ']1='Y CTRL-Y? 1110 STA $3F9 1120 STY $3FA 1130 LDA #$4C 1140 STA $3F8 1150 .ELSE OR &? 1160 STA $3F6 1170 STY $3F7 1180 LDA #$4C 1190 STA $3F5 1200 .FIN 1210 RTS 1220 :3 1230 .EM |
Just include this definition at the beginning of your program. Then macro can then be called like this:
2000 >VECTOR,Y |
to set the control-Y vector, or like this:
2000 >VECTOR,& 2010 START ... |
to set the ampersand vector. (Actually any character other than Y will result in setting the & vector.)
(Note: When I showed this macro to Bob I asked him if the .DO in line 1100 would really work. He looked at it for a minute and said, "yes, it sure will. The assembler's macros are even more powerful than I thought!"...Bill)
I have received several calls by subscribers who wonder about the ad from Hardcore magazine. The ad prices a subscription at $20, but does not say clearly what $20 buys.
To my knowledge, HARDCORE has published two issues so far: the first one about a year ago, and the second about six months ago.
Inside the front cover of the first issue you will find the following message:
"Attention Subscribers: Although presently only a quarterly magazine, HARDCORE Computing will go bimonthly and then monthly as soon as possible. Meanwhile, your one-year subscription is for the 4 quarterly issues plus 8 UPDATEs (printed on the other 8 months) and all ALERT Bulletins sent out whenever we feel information is too important to wait. The UPDATEs will be reprinted in part or in whole in the next magazine. The magazines, UPDATEs, and ALERT Bulletins comprise the subscription package."
I have talked with the publisher, Chuck Haight, several times on the phone. I believe he intends to fulfill every subscription, but he is having trouble getting the magazine out on a regular schedule. I asked him how often the magazine is published, and he answered "Very infrequently". He did re-assure me that a subscription buys four issues.
Note that Softkey Publishing is another company with the same people. Two callers indicated they are quite satisfied with the software they bought from Softkey.
While working on the FLASH! Integer BASIC Compiler I ran into a nasty little problem because the compiled code ran too fast! That's right, too fast. The old problem with reading the game paddles too soon after one another rose to byte (punny huh!) me once again.
Basically the game paddle problem is that they are read with a variable time delay loop. Because one paddle may read significantly faster than another, and the paddles have only one trigger to fire all four of the paddles, you might process the data fast enough to be ready to read the next paddle before it has finished its previous time delay. This problem is real and occurs in many of the game programs to be found on the Apple. Even Raster Blaster has the problem in its jittery ball release thrust adjuster.
In the example below paddle 0 and 1 are triggered by the $C070 paddle I/O trigger address. But because paddle 0 has a smaller value, it finishes before paddle 1. If you read one paddle after another with little other processing then one paddle seems to affect the value of the other one. Many programmers have shown this problem to their dealer thinking that they have found a new bug in the Apple but the only problem (if one exists) is the lack of independent paddle triggers for each of the four paddles.
The problem appears if you use the following BASIC program and play with the paddle adjustments. Turn paddle 1 to the middle of its scale and paddle 0 to the low end of its scale and you will see changing paddle 0 affects the value read for paddle 1. You will find that paddle 1 will vary by 20-40 counts without even touching it.
10 PRINT PDL(0),PDL(1) : GOTO 10 +-------+ -| |----------------- paddle 0 +---------------+ -| |---------- paddle 1 ^ ^ : : paddle expires : paddles are triggered at this time
So what can be done about the problem? What I did is design a routine that reads the paddle without triggering it and waits for the paddle to shut off. This is easily done by calling the monitor paddle read routine at $FB21, skipping the trigger instruction at $FB1E. This takes care of much of the problem, but I still found it necessary to add a tiny delay loop before triggering the paddle. The extra delay is probably due to the remaining charge in the internal capacitor in the timer chip.
The assembly language routine which follows is basically what I added to the FLASH! compiler runtime package to take care of its being too fast for its own good! This explains 14 of the 36,000 bytes of object code in the FLASH! Compiler system. There is also a DEMO program which reads both paddles and displays the values in hexadecimal so you can test the routine.
1000 *-------------------------------- 1010 * READ PADDLES 1020 * PADDLE NUMBER IN A REGISTER 1030 * USES A,X,Y REGISTERS 1040 * RETURNS PADDLE VALUE IN Y REGISTER 1050 *-------------------------------- 1060 * THIS PADDLE READ ROUTINE 1070 * WILL PREVENT ALMOST ALL PADDLE 1080 * INTERACTION PROBLEMS DUE TO 1090 * ONLY 1 PADDLE TRIGGER FOR 1100 * ALL PADDLES. 1110 *-------------------------------- 1120 MON.PREAD .EQ $FB1E 1130 *-------------------------------- 1140 READP AND #3 PDL 0 - 3 1150 TAX 1160 JSR MON.PREAD+3 MAKE SURE PADDLE IS READY 1170 LDY #0 1180 .1 DEY KLUDGE DELAY FOR 1190 BNE .1 CIRCUIT READY 1200 JMP MON.PREAD TRIGGER AND READ 1210 * PADDLE RESULT IN Y REGISTER 1220 *-------------------------------- 1230 DEMO LDA #0 READ PADDLE 0 1240 STA $24 HTAB COLUMN 1 1250 JSR READP 1255 TYA VALUE TO A 1260 JSR $FDDA PRINT VALUE IN HEX 1270 INC $24 LEAVE SPACE ON SCREEN 1280 LDA #1 READ PADDLE 1 1290 JSR READP 1295 TYA VALUE TO A 1300 JSR $FDDA PRINT VALUE IN HEX 1310 JMP DEMO AGAIN AND AGAIN... |
Bob Broedel has been keeping track of all the books, magazines, etc. that are of interest to Apple owners. The last time I saw the list (May 1982), it was ten pages, two columns. Each entry includes all the bibliographic data Bob knows, so that you can find the items you want.
This is the most complete list I have ever seen. If you want a copy, he will send you one for $2. Write to Bob Broedel, P. O. Box 20049, Tallahassee, FL 32304.
Sometimes the standard Apple Monitor screen functions are too slow. No reflection on Steve Wozniak, because he wrote them to be general and compact rather than quick.
I am thinking particular of the screen clear (HOME to Applesoft users) and the screen scroll subroutines. They were both written to operate on a text window, not necessarily the whole screen. But most of the time you do want to clear or scroll the whole screen.
The primary text screen memory is mapped into the addresses from $400 through $7FF, but not in an obvious or straightforward way. This table shows the actual memory addresses for each screen line:
Line Addresses Line Addresses Line Addresses 0 $400-$427 8 $428-$44F 16 $450-$477 1 $480-$4A7 9 $4A8-$4CF 17 $4D0-$4F7 2 $500-$527 10 $528-$54F 18 $550-$577 3 $580-$5A7 11 $5A8-$5CF 19 $5D0-$5F7 4 $600-$627 12 $628-$64F 20 $650-$677 5 $680-$6A7 13 $6A8-$6CF 21 $6D0-$6F7 6 $700-$727 14 $728-$74F 22 $750-$777 7 $780-$6A7 15 $7A8-$7CF 23 $7D0-$7F7
Note that 120 consecutive bytes are used for three text lines spaced at an 8-line interval. Then 8 bytes are not used. Then the next 120, and so on. Those 8 sets of 8 bytes that are not used by the screen mapping are used by peripheral cards and DOS for temporary storage. In the standard Apple Monitor subroutines, a subroutine named BASCALC at $FBC1 calculates the starting address for a specified line. Then the various screen functions use that address, which is kept up-to-date in BASL,BASH ($28,29).
In the listing that follows, I have included fast subroutines to clear the entire text screen (CLEAR); to set the entire text screen to whatever character is in the A-register (SET); to clear the entire Lo-Res Graphics screen (GCLEAR); and to scroll the entire text screen up one line. For demonstration purposes, I also wrote routines to set the entire screen to each value from $00 through $FF; to alternate the screen between solid black and solid white until a key is pressed; to scroll end-around, placing the old top line on the bottom of the screen while moving the rest of the lines up; and to continuously scroll end-around until a key is pressed.
For comparison, I counted that the Wozniak's screen clear takes 15537 microseconds; mine takes only 5410 microseconds. The fastest possible would be one LDA #$A0 followed by 960 "STA $xxx" and an RTS; that would take 3848 microseconds. (All these times round off the Apple's cycle time to one microsecond; actually it is a little faster.)
1000 * S.SCREEN TRICKS 1010 *-------------------------------- 1020 * FAST SCREEN CLEAR SUBROUTINE 1030 *-------------------------------- 1040 GCLEAR LDA #0 1050 .HS 2C SKIP OVER NEXT TWO BYTES 1060 CLEAR LDA #$A0 1070 SET LDY #119 1080 .1 STA $400,Y LINES: 0 8 16 1090 STA $500,Y 2 10 18 1100 STA $600,Y 4 12 20 1110 STA $700,Y 6 14 22 1120 STA $480,Y 1 9 17 1130 STA $580,Y 3 11 19 1140 STA $680,Y 5 13 21 1150 STA $780,Y 7 15 23 1160 DEY 1170 BPL .1 1180 RTS 1190 *-------------------------------- 1200 * SET SCREEN TO ALL VALUES 1210 *-------------------------------- 1220 SETALL LDX #0 1230 .1 TXA 1240 JSR SET 1250 INX 1260 BNE .1 1270 RTS 1280 *-------------------------------- 1290 * ALTERNATE SCREEN UNTIL KEY PRESSED 1300 *-------------------------------- 1310 ALTER LDA #$20 INVERSE BLANK 1320 JSR SET 1330 JSR CLEAR 1340 LDA $C000 1350 BPL ALTER 1360 STA $C010 1370 RTS 1380 *-------------------------------- 1390 * FAST SCROLL UP SUBROUTINE 1400 *-------------------------------- 1410 SCROLL LDY #119 1420 .1 LDA $400,Y SAVE LINES: 0 8 16 1430 PHA 1440 LDA $480,Y MOVE 1>0, 9>8, 17>16 1450 STA $400,Y 1460 LDA $500,Y MOVE 2>1, 10>9, 18>17 1470 STA $480,Y 1480 LDA $580,Y MOVE 3>2, 11>10, 19>18 1490 STA $500,Y 1500 LDA $600,Y MOVE 4>3, 12>11, 20>19 1510 STA $580,Y 1520 LDA $680,Y ET CETERA 1530 STA $600,Y 1540 LDA $700,Y 1550 STA $680,Y 1560 LDA $780,Y 1570 STA $700,Y 1580 PLA MOVE 8>7, 16>15 1590 CPY #40 1600 BCC .2 DISCARD OLD LINE 0 1610 STA $780-40,Y 1620 .2 DEY 1630 BPL .1 1640 RTS 1650 *-------------------------------- 1660 * SCROLL AROUND, MOVING TOP LINE TO BOTTOM 1670 *-------------------------------- 1680 SCR LDY #39 SAVE TOP LINE ON STACK 1690 .1 LDA $400,Y 1700 PHA 1710 DEY 1720 BPL .1 1730 JSR SCROLL SCROLL SCREEN UP ONE LINE 1740 LDY #0 STORE OLD TOP LINE 1750 .2 PLA ON BOTTOM OF SCREEN 1760 STA $7D0,Y 1770 INY 1780 CPY #40 1790 BCC .2 1800 RTS 1810 *-------------------------------- 1820 * ROTATE SCREEN UNTIL KEY PRESSED 1830 *-------------------------------- 1840 S JSR SCR SCROLL AROUND ONCE 1850 LDA $C000 ANY KEY PRESSED? 1860 BPL S NO, SCROLL AGAIN 1870 STA $C010 YES, CLEAR STROBE 1880 RTS ...AND RETURN |
The VIDEX 80 column board patches for the S-C Macro Assembler in last months Apple Assembly Line was a welcome article for me. You see I bought a VIDEX board last November but have no software to run it. I've been planning to write a program development editor similar to the one I used at Texas Instruments, but so far I haven't had the time between the FLASH! compiler, MIKE'S MAGIC MATRIX and the American Heart association CPR Training system.
The patches were very usable, but a major problem still existed to prevent my use on a regular basis. The right arrow key would not copy characters from the VIDEX screen. Try to copy a file name from your catalog with that limitation!
I knew it could be done, because the VIDEX software in ROM has to do that function. Don Taylor mentioned last month that he didnt know the right routine to call and his ROM differed from the listing in the VIDEX manual. My listing was a little off also from my ROM, but I didn't care becase I wasn't going to call the ROM routines.
I used the VIDEX manual's listings to locate the section that performed the copy-character-from-screen function and used similar code in the RDKEY routine of last month's VIDEX patches for the Macro assembler. The 'BNE' to '.3' was changed to go to 'CTRLU' and the copy function coded to process the right arrow key for the VIDEX 80 column board.
I needed two temporary variables to save the X- and Y- registers, so I used the first two bytes of the normal Apple text screen at $400 and $401. Another temporary variable is at $402. Since the normal Apple text display is not operative while the VIDEX is enabled you can use it for temporary variable space without it affecting the screen display. If you try a trick like this some time, you must be careful because some of the monitor routines like HOME and SCROLL can easily zap your storage when you least expect it.
With this new capability of the right arrow key functioning as expected, I am able to use the VIDEX patches often in my software development work. But there are a few problems left yet to solve that I didn't get to look into before writing this article. They are:
The listing that follows should replace lines 4020 through 4420 of the listing on pages 21 and 22 of the August 1982 issue.
The source code on the AAL Quarterly Disk #8 will have these lines already merged with Don Taylor's patches.
4020 *-------------------------------- 4025 V.BASEL .EQ $478+SLOTNUM 4030 V.BASEH .EQ $4F8+SLOTNUM 4035 V.CHORZ .EQ $578+SLOTNUM 4040 V.XSAV1 .EQ $402 4045 V.OLDCHAR .EQ $678 4050 * 4055 V.DEV0 .EQ SLOTNUM*16+$C080 4060 V.DISP0 .EQ $CC00 4065 V.DISP1 .EQ $CD00 4070 *-------------------------------- 4075 * 4080 RDKEY LDA KEYBOARD 4085 BPL RDKEY 4090 STA KEYSTROBE 4095 ORA #$80 4100 CMP #$81 Shift lock? 4105 BNE .1 4110 .DO LCVERSION 4115 JSR UNPROTECT.LC.RAM 4120 .FIN 4125 LSR SCM.SHIFT.FLAG 4130 BPL .2 Return with errant key 4135 .1 CMP #$9A Shift unlock? 4140 BNE CTRLU No, return with key 4145 .DO LCVERSION 4150 JSR UNPROTECT.LC.RAM 4155 .FIN 4160 SEC 4165 ROR SCM.SHIFT.FLAG 4170 .2 LDA #$96 Return with errant key 4175 .DO LCVERSION 4180 BIT $C080 Reprotect LC RAM 4185 RTS 4190 * 4195 UNPROTECT.LC.RAM 4200 BIT $C083 Enable Bank 2 4205 BIT $C083 4210 .FIN 4215 RTS 4220 * 4225 CTRLU CMP #$95 CTRL-U COPY KEY 4230 BNE .3 4235 STX $400 4240 STY $401 4245 LDA V.CHORZ 4250 JSR PSNCALC 4255 BCS .1 4260 LDA V.DISP0,X 4265 BCC .2 4270 .1 LDA V.DISP1,X 4275 .2 ORA #$80 4280 STA V.OLDCHAR 4285 LDX $400 4290 LDY $401 4295 .3 RTS 4300 * 4305 PSNCALC CLC 4310 ADC V.BASEL 4315 STA V.XSAV1 4320 LDA #0 4325 ADC V.BASEH 4330 LSR 4335 PHP 4340 AND #3 4345 ASL 4350 ASL 4355 TAY 4360 LDA V.DEV0,Y 4365 PLP 4370 LDX V.XSAV1 4375 RTS 4380 *-------------------------------- |
The 6801 microprocessor is an enhanced version of the 6800 cpu. It has 11 new opcodes, plus an additional addressing mode for the JSR instruction. Be sure not to use any of these new opcodes if you are assembling code which must execute in a 6800 system!
JSR direct (9d xx) ABX Add B to X ADDD Add M,M+1 to D ASLD Arithmetic shift left D BRN Branch Never LDD Load D from M,M+1 LSRD Logical shift right D MUL Multiply A * B into D PSHX Push X PULX Pull X STD Store D at M,M+1 SUBD Subtract M,M+1 from D
All except "JSR direct" are easy to avoid when programming for a 6800 cpu: simply don't use them. But the assembler may generate the new "JSR direct" instruction automatically.
If you attempt to use "JSR addr" where "addr" is in page zero, the new direct addressing mode will be used. If you are programming for a 6800 cpu, that is not acceptable. To override the assembler's choice, use ".DA #$BD,addr". You can use a macro "JSR" if you have a lot of them.
Bill Linn's "Blinking Underline Cursor" program generated a lot of interest. However, Allan Blackburn from Fort Worth had a problem with it:
"It works just fine, until you hit RESET or re-boot...then it must be BRUN again to get it back. You can't enter monitor and type 300G, or use CALL 768 from Applesoft. Why doesn't calling the routine reset KSWL and KSWH? It should, but I always end up with $9E81 there. Even though lines 1210-1250 store $09 in $38 and $03 in $39, it seems they never get there. Can you explain this? Please?
Sure, Allan. Line 1250 needs to be changed from RTS to JMP $3EA.
This is a common problem. I had it myself back when DOS first came out. For the first year or so we only had a tiny preliminary manual, and the subject wasn't covered. Now the DOS manual is so large we forget to read it or where to find the information. Look on pages 100-105 of the DOS manual and you will find a full explanation.
Briefly, here is what happens. Lines 1210-1250 DO store the address $309 into #38 and $39. But the next time you print a character, DOS gets control and stores its own input address right on top of yours. DOS's input address is $9E81.
The same thing happens in Applesoft programs if you use IN#1 (for example) instead of PRINT CHR$(4)"IN#1", and then print a character. Note 7b on page 105 tells about CALL 1002, which is $3EA.
Apple Assembly Line is published monthly by S-C SOFTWARE, P. O. Box
280300, Dallas, TX 75228. Phone (214) 324-2050 Subscription rate is $15 per year,
in the USA, sent Second Class Mail; $18 per year sent First Class Mail in USA,
Canada, and Mexico; $28 per year sent Air Mail to 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.)