==(((((((((( == Z*MAGAZINE - ATARI 8-BIT ONLINE MAGAZINE =========(( === ---------------------------------------- =======(( ===== April 24, 1991 Issue #192 =====(( ======= ---------------------------------------- ==(((((((((( == (c)1986-87-88-89-90-91, Z*Net Publishing Rovac Industries, Inc. Post Office Box 59 Middlesex, New Jersey 08846-0059 Z*Net BBS (908) 968-2024 EDITORS DESK ============ by Ron Kovacs This issue contains programming information and a review. The next edition will contain more 8-bit only information and be available next week, April 30, 1991. DEFAULT DRIVER PLUS =================== Reprinted from the Australian Atari Gazette (edited by Ron Kovacs) by Peter Bailey The following short program makes several alterations to the AtariWriter Plus printer driver F (XMM801). Before making any adjustments you should know more about the AP.OBJ file. Each data line contains the total information for each alteration and may be deleted if not required. The format for each line is (XL Version) sector, byte, (XE Version) sector, byte, number of bytes to change and data. In some cases the format is repeated until all the necessary alterations were made. NOTE: DO NOT ALTER THE DATA STATEMENTS. Line 80 changes [SELECT] [.] from Double Strike (two passes) to Bold (one pass). NOTE: Bold is only available with Pica. Line 90 changes [CONTROL] [G] 4 (superscript) and [CONTROL] [G] 5 (subscript) from condensed to current type face or selected type face, e.g. for elite subscript when using pica select elite first and then condensed, [CONTROL] [G] 6 [CONTROL] [G] 5, then return to pica, [CONTROL] [G] 1, when subscript is finished. Line 100 allows selection of condensed after using elite. Previously this was not possible as elite was not cancelled first. This is done by having condensed first select pica (to cancel elite) and then sending the required printer code. EO 10 V=2:OPEN #1,12,0,-D:AP.OBJ-:NOTE #1,S1,B1:S2=S1+194:B2=B1+20 YW 20 POINT #1,S2,B2:GET #1,A:IF A=224 THEN V=1:REM XL VERSION QF 30 READ A:IF A=-1 THEN 70 EI 40 READ B,C,D,E:S=S1+A:B=B1+B GI 50 IF V=2 THEN S=S1+C:B=B1+D PN 60 POINT #1,S,B:FOR X=1 TO E:READ Y:PUT #1,Y:NEXT X:GOTO 30 YA 70 CLOSE #1:END LG 80 DATA 191,123,27,57,1,70,192,1,27,60,1,69 CJ 90 DATA 192,42,27,101,1,17,192,51,27,110,1,17 SQ 100 DATA 192,15,27,74,19,7,27,19,27,84,27,112,0,9,27,19,27,20,27,84,27,112,0,6 FY 110 DATA -1 The screen color of AtariWriter Plus is 144. If you would prefer a less contrast border, why not use 146 instead of 0. To make the change, simply add the following line to the above listing. You may prefer to preview the combination first, so with BASIC type 'POKE 710,144:POKE 712,146'. THE WORKBENCH ============= (Reprinted from the Mid-Florida Atari Computer Club Bulletin) by Len Spencer This is probably one of the last articles original to me for a while, but I will try to bring you some of the best fixes, modifications, and other projects of other authors in the coming months. In this article however, I will try to give a little help on fixing one of the more common breakdowns, the keyboard. I'm sure quite a few of you have an Atari in the closet with a keyboard that has gone belly-up in one way or another. You would like to put that machine to use again, or would like to sell it for the best price as a working computer, so let's dig right in. The 400's membrane keyboard was a joke from the git-go. The only solution there is replacement, and a lot of people replaced them with third party keyboards. Since there were so many manufacturers, I can't even begin to cover them all here. With the 800's, as well as the 800XL, there were more than one design of keyboards, by far the most durable of which was the full stroke, contact-switch type. Stackpole was one of the major manufacturers here. While I'm notsure about what percentage of 800's used this type, not many of the 800XL's had them. If you should happen to have an 800 or 800XL with a Stackpole keyboard, then you should have very little if any problems with it. If you lose function of a key here, a nice bath with a good tuner cleaner will take care of even the nastiest keys. If that doesn't work, then the keyswitch can be replaced. The other was the printed circuit contact sheet, where conductive paint traces were silkscreened onto plastic sheets. My 800 is one of these, manufactured by Mitsumi, and a lot of the 800XL's were made by Chelco. Here you must exercise a little more caution. DO NOT use any solvent type cleaner or you will wash the traces right off. The only thing you can use here is a little water and a soft cloth. Even alcohol will discolor the traces and raise the resistance. If a trace is broken, a little dab of conductive paint, available at any electronic supply store, will fix it up nicely. If the key still doesn't work, try giving the spring that presses against that contact a little stretch. Be careful here, as it is easy to go too far and have the key stick on all the time. Remember, it is easier to stretch a spring than it is to shorten it, (cutting it is -NOT- an acceptable alternative!!). If the problem is a key sticking on all the time, try it with the pressure spring removed. If it stops repeating, then shorten the pressure spring by squeezing it down with gentle pressure. If it still sticks, then take the separator sheet (the one with all the holes in it), and add a piece of scotch tape over the corresponding hole, and cut out the tape where it covers the hole. Don't use masking tape or anything like that, as it is too thick. You should never use more than two layers of scotch tape for this type of repair. If it still sticks after two, then replace the keyboard or use the computer for parts. There are quite a few 800XL's floating around that can be had for a more-than-reasonable price, and you should be able to find one with a working keyboard. The 130XE was a radical departure from the others, in it used only a single sheet of plastic, with a contact on the bottom of the keyshafts bridging two contacts on the sheet. Here if cleaning doesn't help, save yourself a lot of aggravation and replace the keyboard. If you've found everything to be fine and dandy with the keyboard itself, but you don't have function of a group of keys, check the ribbon connector where the keyboard connects to the computer. There may be a bad connection. On the 800 this shouldn't happen, as this is a full plastic-bodied 18-pin connector. On the 800XL, the ribbon is merely an extension of the silk-screened sheet that slips into a connector on the main board. If part of the conductive paint has been scrapped away, you can reach fresh trace by trimming down the ribbon a little. If you find yourself having to go too far, then replace the keyboard. Sometimes the problem is on the main board itself. The keyboard is read by two 4051 decoders and fed into the POKEY chip. Try swapping out the chips, one at a time, and eventually the keyboard should come back to life. If not, then there is a more serious problem that requires professional attention. Hopefully, I have given you enough information here to enable you to do your own keyboard repairs and save a little money. ADVENTURE SYNTAX MAGAZINE ========================= Adventure = SYNTAX = Magazine Why should you try it? * It's the only ST disk magazine dedicated to adventures and RPGs. The first issue was produced in July 1989. The magazine is bi- monthly and is available in colour or mono versions and all issues are STE-compatible. * Each issue so far has contained several screenshots and an average of: 10 solutions (some with maps, some serialised) 11 reviews including some adventure-related book reviews 12 files of hints * The specially designed SynTax 3-in-1 hints give two levels of hints - subtle or sledgehammer - depending how desperate you are! * Each disk contains news, letters, and various information sections including a reference list of ST adventure/RPG software which is being continually updated. * The SynTax PD library contains over 150 disks of adventure-related software including games, map disks solutions and demos. If you make a contribution to SynTax on disk, you can pick a PD disk to replace it - free! * SynTax has had favourable reviews in all the major glossy magazines and the disks build up into a useful reference collection. * At only 3 Pounds 50 Pence an issue or 20 Pounds for a year's subscription of six issues in the UK/Europe (Five Pounds 25 Pence / Thirty Pounds overseas by airmail) can you afford NOT to try it? ---------------------------------------------------------- To: SynTax, 9 Warwick Road, Sidcup, Kent DA14 6LJ ENGLAND Please send me the current issue/ the next six issues of SynTax in colour/mono Cheques/POs etc should be made payable to S Medley - all payment in Sterling please. Name.................................................... Address................................................. ............................... Postcode................ THE ABC COMPILER ================ by Mark Farmer, S*P*A*C*E (Reprinted from the Puget Sound Atari News, May 1990) If you 8-Bit Atari users would like to speed up your Basic programs so that they run like the high speed and memory efficienct compiled languages such as Forth, -C-, Action, or Assembler then, do I have a Basic compiler for you! Monarch Data Systems has a Basic compiler called the ABC Compiler that will translate your Basic programs into compact pseudo-code, also known as p-code. Once compiled this p-code can be executed like any other binary program. ABC compiled programs run from four to twelve times faster than the original Basic program, depending on how well the source code is written. This makes it possible to use compiled Basic for professional game developement and other speed critical applications. I first bought the ABC Compiler back in 1983. I own version 1.03, but know that it has been upgraded twice since I purchased it and now is at version 1.05. The ABC Compiler was the best back then and is the only Basic compiler out for the Atari 8-bit (the DataSoft and MGM compilers are no longer made). Even if these two compilers were still out the ABC Compiler is the easiest to use. I am very happy with the ABC Compiler (a job hard to do, ask my wife). The ABC Compiler is cheaper now than it was when I originally purchased it ($50.00). The compiler comes with the program disk and a well put together manual that tells you how to use it. I highly recommend this Basic compiler. If you have any questions about the ABC compiler you can send a letter to me at: SSG Mark S. Farmer A Co. 1/506 Inf APO, SF 96251 The address and phone number for Monarch Data Systems is as follows: Monarch Data Systems, Inc. 25 Cambridge Ct. Morganville, NJ 07751 Phone: (201) 591-9774 THE 8-BIT DCB A Programming Tutorial ============= by Dan Knauf of S*P*A*C*E (Reprinted from the Puget Sound Atari News, March 1991) Something that a lot of people seem to have a hard time learning to understand is the Device Control Block (DCB) in the Atari Computer. Actually, there are two of them - the one available to any programmer located in page 3 (memory location $300 or 768 in decimal) and the one located in zero-page that is used by the operating system and DOS. For now, we'll just worry about the one in page 3. The main purpose of the DCB is to provide a uniform method of talking to any periphials attached to the computer. In the 8-bit Atari, this includes items attached to the SIO port and (for XL's and XE's) the expansion port. This includes such interesting devices as disk drives, cassette drives, hard drive interfaces, and the 850 interface to name a few. To keep this as simple as possible, we'll just talk about disk drives. This information pretty much applies to all periphials though. The DCB is a table containing 12 bytes of information that is required by the operating system to talk to any and all these periphials. This info includes a device identifier (to specify D:, P:, etc.), a device unit number, a command byte, a status byte, a buffer address, a timeout byte, a buffer size, two auxilliary bytes, and one spare (unused) byte. Here is a list of the addresses and the official Atari names of each of these fields: * Hex Dec Name Purpose ------------------------- *$300 768 DDEVIC Buss ID *$301 769 DUNIT Unit number *$302 770 DCOMND Command *$303 771 DSTATS Status *$304 772 DBUFLO Lo byte of buffer address *$305 773 DBUFHI Hi byte of buffer address *$306 774 DTIMLO Timeout value *$307 775 DUNUSE Spare byte - unused *$308 776 DBYTLO Lo byte of buffer size *$309 777 DBYTHI Hi byte of buffer size *$30A 778 DAUX1 Auxilliary byte #1 *$30B 779 DAUX2 Auxilliary byte #2 Once this table has been set up with the correct data, all that is necessary to talk to a periphial is a call to the operating systems Serial Input Output Vector (SIOV) located at address $E459 (58457 decimal). So if it's so easy, what goes in the table? Well, here is an expanded description of each item in the DCB and, where appropriate, legal values and their purpose. DDEVIC is used to select a particular periphial. For now we'll just worry about talking to a disk drive. To do that DDEVIC must contain a $31 (49) which is the ID value for disk drives. DUNIT is used to select the unit number. To talk to drive one, a value of 1 must be in DUNIT. For drive two, a 2 and so on. DCOMND is the command to be executed. There are several valid commands, some of which are: * Format $21 33 * Format enhanced $22 34 (1050 compatibles only) * Get configuration $4E 78 * Set configuration $4F 79 * Put (no verify) $50 80 * Read $52 82 * Status $53 83 * Write (w/verify) $57 87 There are some other commands but these are the most useful and will allow you to do just about anything with a disk drive. DSTATS is an interesting part of the table and the one I tended to forget about the most when I was learning how to use the DCB. First, it holds the status of the operation after a call to SIOV. If it is greater than 127 an error has occured and the number contained here is the Atari number for the error encountered. For example, a 138 here means the device addressed is not on-line (device time-out). Second, (the part I kept forgetting) it is used to indicate the direction of any data transfer to be peformed during the execution of the command. To send data do the drive, POKE $80 (128) here. To receive data from the drive POKE $40 (64). For commands not involving any data POKE a 0 in this location. Virtually all commands involve the transfer of some data so a zero isn't used here too often. DBUFLO and DBUFHI contain the address of the data buffer. If you are sending data, it will be sent from this address. If you are receiving data it will received at this address. Example: HI=INT(BUFADR/256):LO=BUFADR-256*HI:POKE DBUFLO,LO:POKE DBUFHI,HI. DTIMLO is used to set the amount of time you want to system to wait on the periphial in seconds. I use a value of 7 a lot here. The default value is something over 30 seconds and I am an impatient sort. Usually if 7 seconds isn't long enough 30 isn't going to be either. The exception is the format command. I use a value of $F8 (248) because the format takes lotsa time. DBYTLO and DBYTHI are used to indicate the number of bytes to transfer. This usually 128 (for single or enhanced density disks) or 256 (double density). Example: HI=INT(SIZE/256):LO=SIZE-256*HI:POKE DBYTLO,LO:POKE DBYTHI,HI. DAUX1 and DAUX2 contain the number of the sector to be read or written to. As with all the two byte fields this data is stored in 6502 format. Ie., the low byte is in DAUX1 and the high byte is in DAUX2. For example, to read sector 1 DAUX1 would contain a 1 and DAUX2 would be zero. Example: HI=INT(SECTOR/256):LO=SECTOR-256*HI:POKE DAUX1,LO:POKE DAUX2,HI. This concludes the description of the DCB. Now let's look at some of the commands and how they are used. First comes the get configuration command. Before doing any reading or writing to the disk you must know what density it is in so you know whether to write 128 or 256 bytes to a sector. The exception to this is sectors 1-3. They are ALWAYS 128 bytes long. All drives I know of except the 810 contain a 12 byte configuration table that is user alterable. This table sets the density among other things. Here is a listing of the drive configuration table. *Byte # Purpose* * 1 Number of tracks * 2 Step rate * 3 Sectors per track - Hi byte * 4 Sectors per track - Lo byte * 5 number of heads -1 * 6 Density 0=single 4=Double or Enhanced * 7 Bytes per sector Hi byte * 8 Bytes per sector Lo byte * 9 Drive present flag * 10 Not used (Stock XF551 returns a $41 here) * 11 Not used * 12 Not used Notice that the two-byte values are NOT in 6502 format. The high byte of these values comes first! Another thing to be aware of is that hard drives use some of these locations a little differently. The number of heads is invalid for hard drives. And the first two bytes of the table contain the total number of sectors in the partition instead of tracks and step rate. I know this to be true of the BlackBox interface and think it holds true for the MIO also. To read the table from the drive, you must set up the DCB to receive 12 bytes of data at an address you specify. Then poke $4E (78) into DCOMND and call SIOV. Here is a one line call to SIOV from BASIC. X=USR(ADR(-hLYd-)):REM the 'd' is inverse. Once you have read the configuration look at byte 7. It should be either a 1 or a 0. If it is 0 the disk is single or enhanced density. Otherwise, it is double density (256 byte sectors). This method is not perfect. If you have a Percom drive you should read sector 1 (remember it is always 128 bytes) before getting the configuration to ensure accuracy. Reading sector one does not screw up other drives so it is safe to do under any conditions. Enhanced density disks can confuse the US Doubler and XF551 drives. I personally HATE enhanced density... One of my favorite snivels is -Why couldn't Atari have just used real double density???- (Imagine a loud voice with a strong nasal whine here.) Now that you know how to GET the configuration, you know how to SET it too. You set the DCB up with the same values except for the command which is $4f (79) and DSTATS which is $80 (128). The only values you can set are: Sectors per track (18 for single or double, 26 for enhanced), number of heads (0 or 1), density (0 or 4), and bytes per sector (128 or 256). Note that enhanced density requires a 4 in the density byte and 128 byte sectors as well as 26 sectors per track. The most useful place to use the set configuration command is immediately before issuing a format command. This ensures that the drive will for sure be formatted in the density you want. Some DOSes don't even do this. (Ever try to format a disk with DOS 2.0 that has previously been formatted in double density? Ugh!) The next command to mention is the STATUS command ($53 or 83 decimal). This can also be used to get the density of the drive. Again, the US Doubler can get confused and lie if enhanced density disks are used. (I HATE enhanced .....) To use this command you must set the DCB up to receive 4 bytes from the drive. The bytes received are described as follows: Byte Description ------------------ 1 Command status 2 Controller chip status 3 Timeout value for formatting 4 Unused (current track # for Indus drives) If the first byte of the data returned is greater than 127 then the drive is in enhanced mode (supposedly). Otherwise, if bit 5 is set the drive is in double density. Else the drive is in single density. If bit 3 is set the disk is write protected. Bits 0-2 are error bits. If any are set then some error has occured. Reading and writing sectors is the next thing on the agenda. To read a sector set the DCB up to receive data. Poke the low byte of the sector number into DAUX1 and the high byte into DAUX2. Then call SIOV and your sector will be read into memory - assuming the drive door is closed and there is a readable disk in there and everything. To write a sector do the same thing but set up DCOMND and DSTATS to send data instead of receive it. Finally, let's look at the format command. You must set the DCB up to receive data when you format a disk. The drive will return a bad sector list when the format is completed if successful. So poke a 64 into DSTATS and the address you want the bad sector list returned to in DBUFLO/HI. Also, poke a 0 in DBYTLO and a 1 in DBYTHI since the list can be 256 bytes long. Immediately after the format command, check for an error as described below. Then check the first two bytes of the bad sector list buffer. They should both be 255. If they aren't then there are bad sectors on the disk. Errors! Well, they are bound to happen sometime. Immediately after your call to SIOV you should PEEK(DSTATS) and make sure the value there is not less than zero. If it IS greater than 127 then an error has occured. If this happens, the value in DSTATS is the same value that would normally show up in location 195 if BASIC had generated an error. BASIC will NOT see or TRAP any errors that happen when you talk to the disk drive through the SIOV. So, make sure you check for them yourself. Don't get discouraged if your first attempt at doing direct sector I/O isn't successful. It took me some time to get comfortable with this method of communicating with periphials and I made some dandy mistakes too. I have even managed to format a partition or two on my hard drive. It'd probably be a pretty good idea to make sure you have a scratch disk in the drive when you do your experimenting.... Anyone interested in the IOCB's? There's 8 of those! Aw... maybe next month... A TRIO FOR TURBO BASIC ====================== by John Picken, GCACE Here are three short and easy programs. The first is a -fix-, the second is a MyDOS 4.5 -mod- and the third is a new utility. Note that all three programs will only run under Turbo BASIC which is readily available to any user group member. There are two reasons for this: first to demonstrate some of Turbo's fine features and, more importantly, programming in Turbo is about ten times easier than in Atari BASIC (laziness wins again). My original version of MYDOS RAMDISK AUTOLOADER, that was published in the July PSAN, fits the expression -too smart by half-. It works fine with 256K because, on the 256XL, an unformatted RAMdisk shows -65535 FREE SECTORS- which tells the loader formatting is needed. The rub is that an unformatted RAMdisk with the 320XE shows -255 FREE SECTORS-. Since this could mean a nearly full, formatted RAMdisk, the loader doesn't format. Program A fixes the existing autorun file for the 320XE; it replaces the -smart- code with -smarter- NOP's so the loader formats any time DUP.SYS is not found in the RAMdisk. Apologies to any 320XE owners who have been -blue-ifying- the air. Program B makes a modification to MyDOS 4.5 DUP.SYS which results in different default colours and keyboard parameters. I find a white on black display to be more readable on a monochrome monitor but you are free to select any colors you like. The values for the keyboard produce a fast, quiet cursor; to change them, refer to page 208 in MAPPING THE ATARI. If you do something that results in a GRAPHICS 0, (Copy to/from S: or E:, load Turbo BASIC, etc.) the colors revert to normal but the keyboard parameters remain as set until you hit RESET. The modification uses two loops which is why COLOR3 and HELPFG are included - just leave them at 70 and 0. All internal changes are made so that your modified DUP will be written if you -Write DOS Files- from DUP. Program C produces a short machine language file that switches BASIC off or on. It is a toggle - if BASIC is on, it will be turned off; if off, it will be turned on. You can load the program anytime and/or, include it in an autorun file (it should be first with others appended to it). As an autorun, it has the effect of reversing the OPTION key so that you would need to press OPTION to enable BASIC at boot. 10 REM Program A: 320XE RDLoader Fix 11 DIM PRG$(700),JSR_AFP$(3) 12 PRG$(700)=CHR$(0) 13 JSR_AFP$=CHR$(32) 14 JSR_AFP$(2)=CHR$(0) 15 JSR_AFP$(3)=CHR$(216) 16 OPEN #1,4,0,-D1:AUTORUN.SYS- 17 TRAP #EOF 18 BGET #1,ADR(PRG$),LEN(PRG$) 19 # EOF:CLOSE 20 PRG$=PRG$(1,DPEEK($0358)) 21 PATCH=INSTR(PRG$,JSR_AFP$) 22 FOR B=0 TO 11 23 __PRG$(PATCH+B,PATCH+B)=CHR$(234) 24 NEXT B 25 OPEN #1,8,0,-D1:AUTORUN.SYS- 26 BPUT #1,ADR(PRG$),LEN(PRG$) 27 END 10 REM Program B: Modifier for 11 REM . MyDOS 4.5 DUP.SYS 12 DIM DUP$(7000) 13 DUP$(7000)=CHR$(0) 14 TRAP #EOF 15 OPEN #1,4,0,-D:DUP.SYS- 16 BGET #1,ADR(DUP$),7000 17 # EOF:CLOSE 18 DUP$=DUP$(1,DPEEK($0358)) 19 REM Code changes inside DUP 20 RESTORE #IN_MODS 21 FOR COUNT=1 TO 14 22 __READ INDEX,BYTE 23 __DUP$(INDEX,INDEX)=CHR$(BYTE) 24 NEXT COUNT 25 # IN_MODS:DATA 5,78,30,32 26 DATA 31,50,32,67 27 DATA 326,52,1682,79 28 DATA 1690,79,2385,78 29 DATA 2389,26,2393,5 30 DATA 2779,79,2986,79 31 DATA 5839,54,5840,48 32 REM Code added to end of DUP 33 RESTORE #ADD_MODS 34 FOR COUNT=6639 TO 6659 35 __READ BYTE 36 __DUP$(COUNT)=CHR$(BYTE) 37 NEXT COUNT 38 # ADD_MODS:DATA 162,4,189,70 39 DATA 67,157,196,2 40 DATA 189,74,67,157 41 DATA 216,2,202,208 42 DATA 241,142,28,2 43 DATA 96 44 REM Default bytes at end of DUP 45 DUP$(6660)=CHR$(12):REM Colr1 Text 46 DUP$(6661)=CHR$(0):REM Colr2 Bak 47 DUP$(6662)=CHR$(70):REM Color3 48 DUP$(6663)=CHR$(0):REM Col4 Border 49 REM Ref. Mapping The Atari p.208 50 DUP$(6664)=CHR$(18):REM KRPDEL 51 DUP$(6665)=CHR$(2):REM KEYREP 52 DUP$(6666)=CHR$(1):REM NOCLIK 53 DUP$(6667)=CHR$(0):REM HELPFG 54 OPEN #1,8,0,-D:DUP.SYS- 55 BPUT #1,ADR(DUP$),6667 56 END 10 REM Program C: Makes Basic Toggle 11 CLS :? :? :? -BASIC.COM Creator- 12 ? :? -Checking data lines-:? 13 TRAP #EOD1 14 DO 15 __B=B+1 16 __READ A 17 __CS=CS+A*B 18 LOOP 19 # EOD1:RESTORE 20 IF CS=211369 21 __? :? -__Data OK. Insert disk,- 22 __? -push START to write file.- 23 __# KEY:ON PEEK(53279)<>6 GO# KEY 24 __TRAP #DISK_ERROR 25 __OPEN #1,8,0,-D1:BASIC.COM- 26 __TRAP #EOD2 27 __DO 28 ____READ A 29 ____PUT #1,A 30 __LOOP 31 __# EOD2:CLOSE 32 __? :? -BASIC.COM created.- 33 ELSE 34 __? - Sorry, data incorrect.- 35 __# RETRY 36 __? -Please check and re-run.- 37 ENDIF 38 END 39 # DISK_ERROR:? CHR$(253) 40 ? - DISK ERROR #-;ERR:GO# RETRY 41 DATA 255,255,0,1,54,1,162,160 42 DATA 173,1,211,73,2,141,1,211 43 DATA 41,2,141,248,3,240,2,162 44 DATA 192,134,106,162,0,142,75,3 45 DATA 169,72,141,68,3,169,196,141 46 DATA 69,3,169,12,141,74,3,141 47 DATA 66,3,32,86,228,169,3,141 48 DATA 66,3,76,86,228,226,2,227 49 DATA 2,0,1 (This article provided courtesy of the Garden City ACE, P.O. Box 6578, Victoria, B.C., Canada V8P 5N7.) XEP80 STATUS LINE ================= by Michael D. Bjorkman, S*P*A*C*E The XEP80 has a number of special features, not all of which were demonstrated in the DEMO80.BAS program which comes on the handler disk. One of these features is a one line text window below the 24th and last line of the normal 80 column screen display. This extra text line is called the Status Line and is handy for printing error messages, prompting for input, etc. for those cases where you don't want to mess up the regular 24 lines of text. The Status Line is not accessible from BASIC using the PRINT command. Therefore I've written a short ML routine which can be called with a USR command. My program will only print messages to the status line and will not accept input from the status line. That is left as an exercise for the reader. Listing 1 is a short demo I've written which uses my Status Line ML routine. The program first initializes the ML string, then lists half of the program to the screen, then prints a message to the status line, then lists some more of the program, and then erases the status line. Listing 2 is the UNICHECK checksum file for checking your typing. Do not type Listing 2, it is not part of the program. Listing 3 is the source code for the ML string. It was written to be relocateable so that it could be placed in a BASIC string. If you want to use the ML string in your own programs, then you will need lines 110, 120, 210, 220, and 1000-1080. The length of the message which can be printed to the status line should only be limited to the width of screen memory, which is 256 characters. I don't know what happens if more than 80 characters are printed to the screen, however, they should all be there. I haven't tried this, but you should be able to horizontally scroll over to read the rest of the message by using the proper CIO call. I also don't know what happens if you try to print more than 256 characters to the status line. Another exercise for the reader. Also, I haven't built an automatic clearing of the status line into the ML routine. You are responsible for clearing the status line of your messages. That can be done by printing a string of spaces to the status line. See line 170 in Listing 1. LISTING 1 110 DIM ML$(126),MSG$(7) 120 FOR I=1 TO 126:READ BYTE:ML$(I,I)=CHR$(BYTE):NEXT I 130 MSG$=-MESSAGE- 135 LIST 100,170 140 ? -MESSAGE IS STARTING- 150 GOSUB 210 160 FOR DELAY=1 TO 800:NEXT DELAY 165 LIST 180,1080 170 MSG$=- - 180 ? -MESSAGE IS ENDING- 190 GOSUB 210 200 END 210 XPOS=PEEK(85):YPOS=PEEK(84) 220 X=USR(ADR(ML$),ADR(MSG$),LEN(MSG$),XPOS,YPOS) 230 RETURN 1000 DATA 104,104,141,1,1,104,141,0,1 1010 DATA 104,141,3,1,104,141,2,1,104,104,141,4,1,104,104 1020 DATA 141,5,1,162,0,169,20,141,66,3,169,12,141,74,3 1030 DATA 169,152,141,75,3,32,86,228,162,0,169,11,141,66,3 1040 DATA 173,0,1,141,68,3,173,1,1,141,69,3,173,2,1 1050 DATA 141,72,3,173,3,1,141,73,3,32,86,228,162,0,169 1060 DATA 20,141,66,3,169,12,141,74,3,173,4,1,141,75,3 1070 DATA 32,86,228,162,0,169,20,141,66,3,169,12,141,74,3 1080 DATA 173,5,1,9,128,141,75,3,32,86,228,96 LISTING 2. 110 DATA 865,373,529,260,928,972,422,136,892,679,984,28,413,644,592,8717 1000 DATA 136,898,912,282,393,936,643,15,881,5096 LISTING 3. 1000 *= $5000 ; this code is relocatable, however MAC/65 requires 1010 ; the Program Counter be set during assembly with the 1020 ; *= directive even though it will do nothing during 1030 ; the assembly of this code. 1040 ; 1050 ; condition of stack when entering this routine. 1060 ; num of arguments (one byte: thrown away and not used.) 1070 ; buffer addr (hi byte) 1080 ; buffer addr (lo byte) 1090 ; buffer length (hi byte) 1100 ; buffer length (lo byte) 1110 ; xpos (hi byte) 1120 ; xpos (lo byte) 1130 ; ypos (hi byte) 1140 ; ypos (lo byte) 1150 ; 1160 STOR1 = $0100 ; buffer address 1170 STOR2 = $0102 ; buffer length 1180 STOR3 = $0104 ; x position of cursor before entering this routine 1190 STOR4 = $0105 ; y position of cursor before entering this routine 1200 ; 1210 ICCOM = $0342 1220 ICBAL = $0344 1230 ICBAH = $0345 1240 ICBLL = $0348 1250 ICBLH = $0349 1260 AUX1 = $034A 1270 AUX2 = $034B 1280 CIOV = $E456 1290 ; 1300 ; This segment of code stores all the arguments at the top of the 1310 ; stack on the bottom of the stack -- 1320 ; Thus preventing loss of the values if CIO uses the stack. 1330 PLA ; number of arguments on stack 1340 PLA 1350 STA STOR1+1 ; ICBAH 1360 PLA 1370 STA STOR1 ; ICBAL 1380 PLA 1390 STA STOR2+1 ; ICBLH 1400 PLA 1410 STA STOR2 ; ICBLL 1420 PLA 1430 PLA 1440 STA STOR3 ; XPOS 1450 PLA 1460 PLA 1470 STA STOR4 ; YPOS 1480 ; 1490 ; Routine to move cursor to Status Line. 1500 ; Using an XEP80 Special CIO call. 1510 LDX #$00 1520 LDA #$14 1530 STA ICCOM 1540 LDA #$0C 1550 STA AUX1 1560 LDA #$98 1570 STA AUX2 1580 JSR CIOV 1590 ; 1600 ; Routine to print text buffer. 1610 ; Using a Device Independent CIO call. 1620 LDX #$00 1630 LDA #$0B 1640 STA ICCOM 1650 LDA STOR1 1660 STA ICBAL 1670 LDA STOR1+1 1680 STA ICBAH 1690 LDA STOR2 1700 STA ICBLL 1710 LDA STOR2+1 1720 STA ICBLH 1730 JSR CIOV 1740 ; 1745 ; Routine to return the cursor to its original horizontal position. 1746 ; Using a XEP80 Special CIO call. 1750 LDX #$00 1760 LDA #$14 1770 STA ICCOM 1780 LDA #$0C 1790 STA AUX1 1800 LDA STOR3 1810 STA AUX2 1820 JSR CIOV 1830 ; 1834 ; Routine to return the cursor to its original vertical position. 1836 ; Using an XEP80 Special CIO call. 1840 LDX #$00 1850 LDA #$14 1860 STA ICCOM 1870 LDA #$0C 1880 STA AUX1 1890 LDA STOR4 1900 ORA #$80 1910 STA AUX2 1920 JSR CIOV 1930 RTS 1940 .END ======================================================================= Z*MAGAZINE ISSUE #192 APRIL 24, 1991 =======================================================================