|||||| |||||| || || |||||| |||||| || || ||| || || || || ||| |||| |||||| || |||| Your || || || || ||| || || |||||| |||||| || || |||||| |||||| GEnieLamp Computing || |||||| || || |||||| RoundTable || || || ||| ||| || || || |||||| |||||||| |||||| RESOURCE! || || || || || || || ||||| || || || || || ~ WELCOME TO GENIELAMP A2Pro! ~ """"""""""""""""""""""""""" ~ TIPS AND TECHNIQUES: Compressing Hi-Res Graphics ~ ~ Scrolling Text ~ Linear Regression ~ Bezier Curves ~ ~ 65C816 in an Atari? ~ Switching Processes in the GNO Shell ~ ~ HOT NEWS, HOT FILES, HOT MESSAGES ~ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\//////////////////////////////////// GEnieLamp A2Pro ~ A T/TalkNET Publication ~ Vol.5, Issue 32 """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" Publisher.................................................John F. Peters Editor....................................................Tim Buchheim \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\//////////////////////////////////// ~ GEnieLamp IBM ~ GEnieLamp Atari ~ GEnieLamp PowerPC ~ ~ GEnieLamp A2Pro ~ GEnieLamp Macintosh ~ GEnieLamp TX2 ~ ~ GEnieLamp Windows ~ GEnieLamp A2 ~ LiveWire (ASCII) ~ ~ Member Of The Digital Publishing Association ~ GE Mail: GENIELAMP Internet: genielamp@genie.com ////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ >>> WHAT'S HAPPENING IN THE A2Pro ROUNDTABLE? <<< """"""""""""""""""""""""""""""""""""""""""""""""" ~ November 1, 1995 ~ FROM MY DESKTOP ......... [FRM] A2PRO ROUNDTABLE STAFF .. [DIR] Notes From The Editor. Directory of A2Pro Staff. TIPS AND TECHNIQUES ..... [TIP] HEY MISTER POSTMAN ...... [HEY] Compressing Hi-Res Graphics Is That A Letter For Me? DEVELOPERS CORNER ....... [DEV] LIBRARY BIT BONANZA ..... [LIB] News From Online Developers. HOT Files You Can Download. LOG OFF ................. [LOG] GEnieLamp information. [IDX]""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" READING GEnieLamp GEnieLamp has incorporated a unique indexing """"""""""""""""" system to help make reading the magazine easier. To utilize this system, load GEnieLamp into any ASCII word processor or text editor. In the index you will find the following example: A2PRO ROUNDTABLE STAFF .. [DIR] Directory of A2Pro Staff. To read this article, set your find or search command to [DIR]. If you want to scan all of the articles, search for [EOA]. [EOF] will take you to the last page, whereas [IDX] will bring you back to the index. MESSAGE INFO To make it easy for you to respond to messages re-printed """""""""""" here in GEnieLamp, you will find all the information you need immediately following the message. For example: (SMITH, CAT6, TOP1, MSG:58/M530) _____________| _____|__ _|___ |____ |_____________ |Name of sender CATegory TOPic Msg. Page number| In this example, to respond to Smith's message, log on to page 530 enter the bulletin board and set CAT 6. Enter your REPly in TOPic 1. A message number that is surrounded by brackets indicates that this message is a "target" message and is referring to a "chain" of two or more messages that are following the same topic. For example: {58}. ABOUT GEnie GEnie's monthly fee is $8.95 which gives you up to four hours """"""""""" of non-prime time access to most GEnie services, such as software downloads, bulletin boards, GE Mail, an Internet gateway, award- winning multi-player games and friendly chat lines. GEnie's non-prime time connect rate is only $3.00 per hour. Prime Time (8:00 am to 6:00 pm local time on weekdays) is only $5.00 per hour. To sign up for GEnie, just follow these simple steps: 1. Set your communications software to half duplex (local echo) 8 bits, no parity and 1 stop bit, at 300, 1200, 2400 or 9600 baud. 2. Call (with modem) 1-800-638-8369 (US) or 1-800-387-8330 (Canada). 3. Wait for the U#= prompt. Type: JOINGENIE and hit RETURN. When you get the prompt asking for the signup/offer code, type: DSD524 and hit RETURN. 4. Have a major credit card ready, as the system will prompt you for your information. If you need more information, call GEnie's Customer Service department at 1-800-638-9636. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" [EOA] [FRM]////////////////////////////// FROM MY DESKTOP / ///////////////////////////////// Notes From My Desktop """"""""""""""""""""" by Tim Buchheim [A2PRO.GELAMP] o TOP OF THE PAGE >>> TOP OF THE PAGE <<< """"""""""""""""""""""""" ~ A Letter From the Editor ~ GENIE OUTAGES Last month I talked about GEnie's first ten years and how """"""""""""" much it has changed. Well, it is still in the process of change; GEnie is in the middle of both hardware and software upgrades. In the past few weeks, these upgrades have caused some problems with GEnie. I've received a report on these problems and thought I should pass it on so you know what's happening. Here's the report I got: "As many of you have no-doubt experienced, GEnie has recently had some recent unplanned system outages. These outages have been both hardware and software related. The hardware problems have been fixed, and a solution for the software problem is undergoing rigorous testing and is slated to be deployed around mid-November. We apologize for any inconvenience these outages have caused." Here's a chronology of what happened. [GEIS is GEnie's parent company] 10/17 (Tuesday) around 21:10: All members were knocked off line. By 21:45 ''''''''''''''''''''''''''''' GEnie was back on line. The problem was diagnosed as a software problem for which GEIS had a formulated fix. The fix has been undergoing rigorous testing and is slated to be deployed around mid to late November. 10/23 (Monday) and 11/24 (Tuesday) around ~21:00-22:00: On both days, ''''''''''''''''''''''''''''''''''''''''''''''''''''''' GEnie members again were knocked off line. The problem was diagnosed as a hardware problem on GEIS equipment that GEnie requires for operation. On Wednesday, the hardware vendor addressed the incidents by replacing boards that were identified as bad. 10/27 (Friday) around 19:00 - 23:00: Initially, only some clients were '''''''''''''''''''''''''''''''''''' knocked off line, but eventually, all were knocked off. This incident was attributed to a hardware failure on yet another piece of GEIS equipment. This time a power supply blew out. The power supply was replaced that evening, and GEnie service was restored. Each of the incidents displayed the same symptoms, but were caused by different problems. EMAIL WEIRDNESS There have also been some strange things happening with """"""""""""""" Email the past few weeks. GEIS upgraded the internet mail gateway, fixing several bugs but causing a minor problem. As most of you know, you can receive email sent to "yourname@genie.com" as well as "yourname@genie.geis.com" but all outgoing mail is sent with "yourname@genie.geis.com". Or at least it's supposed to be that way. When the INET03# mail connector was upgraded to the new software a few months ago, no one had any problems because it was configured right. The main connectors, INTERNET#, INET#, INET00#, and INET01# were upgraded this week but weren't configured properly, so they send mail as "genie.com" instead of the correct "genie.geis.com".This has caused problems for people on mailing lists, because the mailing lists don't recognize this other address. A temporary solution is to send all mail through INET03# rather than the other connectors, if you need to have it sent with the "genie.geis.com" address. The other connectors may be reconfigured, or they may leave them as "genie.com" since they were scheduled to be set to "genie.com" in a month or so anyway. Once they officially announce that internet mail will be through "genie.com", you should unsubscribe to mailing lists through INET03# and resubscribe through one of the main connectors, so they recognize your "genie.com" address instead of "genie.geis.com". -- Timothy Carl Buchheim Editor, GEnieLamp A2Pro P.S. You might have noticed that this issue is much bigger than usual. Well, I tried to keep it reasonable by not having the "RTC Watch" and "Spotlight On:" columns this month. Look for those next month, unless I decide to skip them again in the interest of keeping download time to a minimum :) P.P.S. Sorry this issue was a few days late, but I had no time to work on before the 1st. :/ [*][*][*] Do you have something to say about GEnieLamp A2Pro? Please post any questions or comments you may have in Category 1, Topic 15 in A2Pro's BB (m530;1). Or, feel free to talk to me (A2PRO.GELAMP) anytime you see me in a Real Time Conference. Readers out there on the Internet: feel free to email me at a2pro.gelamp@genie.com When writing, please tell me where you got your copy of GEnieLamp, if it wasn't on GEnie. I'm always interested to see how many places GEnieLamp ends up :) By the way, the current issue and most back issues are available online in many places. GEnie users should check Library #2 in the DigiPub libraries (DIGIPUB, page 1395;3) Those of you not on GEnie should use gopher software to connect to gopher.genie.com for issues; all recent issues and most older ones are there. [*][*][*] [EOA] [DIR]////////////////////////////// A2PRO ROUNDTABLE STAFF / ///////////////////////////////// By Tim Buchheim [A2PRO.GELAMP] o A2Pro STAFF LIST >>> A2Pro STAFF LIST <<< """""""""""""""""""""""" ______________________________________________ APPLE II PROGRAMMERS & DEVELOPERS ROUNDTABLE _____ ______ ______________________________________________ /_____|/______\ /__/|__| ___|__| Head Sysop: Hangtime (HANGTIME) /__/_|__| /_____/ Your Sysops: Greg Da Costa (A2PRO.GREG) /________|/__/ __ __ __ Todd P. Whitesel (A2PRO.TODDPW) /__/ |__|__/______ /_//_// / Nathaniel Sloan (A2PRO.HELP) /__/ |__|________// / \/_/ Tim Buchheim (A2PRO.GELAMP) [EOA] [FEA]////////////////////////// TIPS AND TECHNIQUES / ///////////////////////////// Compressing Hi-Res Graphics """"""""""""""""""""""""""" By Russell Nielson [R.NIELSON1] o COMPRESSING GRAPHICS o THE PROGRAMS IN THE PIC.COMP10.BXY ARCHIVE Editor's note: This is the first of what I hope will be a """""""""""""" series of articles written by readers. But it will only work if you send in articles! If your article is published, then you will be paid with GEnie usage credits. Any article related to programming Apple II computers will be considered. Those articles which include sample source code are especially good, because the whole point of the series is to provide programmers with ideas and samples, in order to encourage them to write new software for the Apple II! This month's article is about compressing graphics files, and is based on a file in the A2Pro library called PIC.COMP10.BXY which was uploaded by the author of this article. >>> COMPRESSING GRAPHICS <<< """"""""""""""""""""""""""""""" INTRODUCTION As we all know, any type of graphics take up a lot of disk """""""""""" space, and when you have a lot of graphics in one place, disk space can be eaten up very quickly. I'd like to discuss one form of graphics on the Apple II called hi-res graphics, which stands for high resolution graphics. All programmers that have ever programmed on the Apple II in hi-res know that a single picture takes up a whopping 8187 bytes of memory or 17 blocks on a ProDOS disk! When you have many pictures stored on disk they can take up a lot of space. Please be aware that "picture" and "screen" both refer to a single hi-res graphics screen. When developing software that uses graphic screens and pictures, you need to store these picture files on disk, load them into memory, and display them on the hi-res screen. This isn't a problem until you start having multiple pictures, like a title screen, a menu screen, an options screen, a high scores screen, etc.. you are talking a lot of graphic data here! The main problem usually shows up when you only have a certain amount of disk space available for your entire project. For instance, if you are writing a cool game and plan on distributing it on one side of a 5.25" floppy disk, your entire game (were talking all your graphics, code, data, etc) has to fit in 140k! Not only that, but if you want your disk to boot into the game automatically then you need to leave enough space for ProDOS (and BASIC.SYSTEM if part of your program is in Applesoft) to be copied there. As you can see you will run out of disk space rather quickly. During the development of one of my arcade games I had so many graphic screens saved to disk that it really got me sick to see all the disk space going to waste! Not only that but loading an entire 8187 bytes of data just to display one screen takes some time, so I sat back and thought for a moment. I have this rather simple screen, which is practically a black screen with a colored border and a small graphic at the top, which is taking as much disk space as any other screen. I determined that regardless of how complex or how simple the picture may be, it's always the same size. If you cleared the hi-res screen to black (a blank screen) and saved it, it would still be a whopping 17 blocks. The reason behind this is because the graphics screen on Apple computers is simply a chunck of memory that reflects what is seen on the monitor. If you save hi-res screen 1 you would be writing the area of memory from $2000 to $3FFF. This block of memory is always the same size and doesn't change even if the graphic image is very simple. I needed to come up with something here to save space. One solution to saving disk space is to somehow represent the picture on the screen in a different manner that does not take up the full 8187 bytes. Welcome to the world of compression. There are many compression methods around and they are used all the time. For instance, Shrink-It and GS Shrink-It use compression methods when placing files into archives. These programs take each file and compress them down as small as the compression algorithm allows and then stored them into the archive. Take GEnie's Software Libraries for example, most everything is stored in a compressed format (.SHK) because compressed files take up less disk space and cut down on file transfer times. Although the Shrink-It compression routines are quite complex, this does not mean that every compression method is complicated. When writing my routine for compressing the hi-res screen, it had to ensure that no information was lost during the compression so that the original picture would be recreated and displayed on the screen EXACTLY how is was before being compressed. MY COMPRESSION METHOD After loading numerous pictures and examining the """"""""""""""""""""" hex dump of the screens, I began to see repetitious bytes and repeating patterns. I figured that if I could store these repeating sequences of bytes as a single number, or two, then I would be saving space. I used a very simple algorithm that would allow me to represent groups of bytes on the screen in just a couple bytes. Here's what I came up with: All black colors on the screen are either $00 or $80, depending on the color bit. $00 is black #1 and $80 is black #2. Remember that there are two black colors and two white colors available in hi-res. In contrast, all white colors on the screen are either $7F or $FF, again depending on the high bit. So a black line on the hi-res screen would look something like this: 00 00 00 00 00 00 00 00 00 00 Note: All numbers are represented in hexadecimal. """" This segment would be a black line ten bytes wide on the hi-res screen. The same goes for black #2 ($80), white #1 ($7F) and white #2 ($FF). I looked at this and said to myself, "Hmmm.. there's gotta be a better way than to just keep repeating zeroes over and over again wasting space." So I came up with a method. For every $00, $80, $7F, or $FF I find, I will count the number that are in a row, store the color, and then store the number of times this color is repeated. So in the example above, I'd store all those zeroes like this: 00 0A Only two bytes are needed to represent that entire group of zeroes! The above "00 0A" means that color 00 is repeated 10 times! ($0A = 10 decimal). When it comes time to decompress it again, I simply check for a $00, $80, $7F, or $FF and then repeat that color the number of times the repeating byte says! The repeating byte always follows directly after the color byte. For another example, here's how the following segment would compress: Raw: 00 00 00 00 00 FF FF FF FF 7F 7F 7F 7F 7F 7F 7F 80 80 80 80 00 00 Compress: 00 05 FF 04 7F 07 80 04 00 02 See how it works? The more repeating bytes in a row, the more space will be saved! So if you have a picture with lots of black and white areas, then the compression will be excellent. In the above sample, that's over 50% compression! WHAT ABOUT COLORS? After I wrote this routine and tested the compression """""""""""""""""" on various pictures, I still was not satisfied with the results. Why? Well, when I had a picture will lots of black and white areas, this compression scheme worked great, but when I had a picture with lots of colors and hardly any black and white areas, the compression was horrible. The reason was because if there were hardly any repeating black and white bytes, then there was not a whole lot to compress. I started thinking of a better way to compress the screens and for new ideas for better compression. After looking at a few more screen dumps, I noticed that Green, Purple, Red, and Blue colors followed a pattern. Maybe I could use a compression method to represent repeating color? Sure I could! Here's what I came up with: After the examination of the screen dumps, this fact surfaced: Green lines are repeating patterns of $2A and $55 Purple lines are repeating patterns of $55 and $2A Red lines are repeating patterns of $D5 and $AA Blue lines are repeating patterns of $AA and $D5 So a green line on the screen would look like this: 2A 55 2A 55 2A 55 2A 55 2A 55 2A 55 Wow! I see a pattern. I used the same algorithm as the black and white method, but had to add in a little twist for pattern repetition. Since the black and white colors were represented as one byte (00, 80, 7F, FF) they were easy to compress, I just had to store count the number of bytes in a row and store that count (or repeat number) after the color byte. But now things are a little different because two bytes represent a color instead of just one. To handle colors (now meaning that black and white aren't colors), I will use a method for pattern recognition by issuing a comparision of two bytes instead of just one. For example, if I was compressing a screen and I came across a $2A, I'd immediately check the byte following it and see if it was a $55. If it was, then I would have found a pattern! I'd go on an count how many of these patterns were in a row and store that repeat value as the repeating byte. So in the above example, that green line would be stored like this: 2A 55 06 In this case, the "2A 55" is the pattern for a green line and the "06" means that there are six of these patterns in a row. When I'm decompressing this screen and I came across the $2A byte, and after I made sure that the next one after it was $55, then I would go ahead an repeat this pattern 6 times! The same thing goes for Purple, Red and Blue. Except that I would compare different numbers because the patterns would be made up of different byte combinations. That is basically the extent of my compression algorithm. There are only two cases in my routine, checking for a non-color byte, and checking for a color byte. In the case of checking for a non-color sequence, I'd act on 00, 80, 7F, and FF. In the case of checking for a color pattern, I'd act on $2A/$55, $55/$2A, $D5/$AA, and $AA/$D5 which represent color sequences. Any other values would be stored as normal, non-compressed. DECOMPRESSION Once the screen has been compressed and is stored in this """"""""""""" new format, it needs to be decompressed and end up in its original form. This process works just like the compression method but it is much easier. I start scanning the compressed data and I look for the key values which are 00, 80, 7F, and FF. Whenever I encounter such a value, I take the next byte, which is the repeating value, and store that number of the color value in a row to the screen. So if I came across "00 1D" I'd store twenty-nine 00's in a row. I'd also scan for key color sequences which are $2A/$55, $55/$2A, $D5/$AA, and $AA/$D5. Whenever I find one of these sequences I'd take the next byte, which (again) is the repeating value, and store this pattern that many times. So ifI came across "AA D5 03" I'd store three "AA D5"'s in a row on the screen. DISADVANTAGES Aren't there any disadvantages? Yes, unfortunately there """"""""""""" are a few. The good thing is that all the advantages always outweigh the disadvantages. The only bad part about my compression algorithm is when there is only one $00, $80, $7F, or $FF in a row, it takes one extra byte to store it compressed than it would to leave it decompressed. For instance a single $00 would compress to look like this: 00 01. This is a disadvantage because we started with one byte and ended up with two. The other bad part is when you only have one color pattern in a row like $D5 $AA, it would compress to D5 AA 01. We went from having only two bytes to needing three. The overall advantage is that the compression method always comes out ahead of the game because there are usually lots more repeating bytes in a row than there are single bytes laying around, and because of what I am going to describe below. THERE'S GOTTA BE SOMETHING ELSE With that done I went ahead and did some """"""""""""""""""""""""""""""" more compressions and studied the results. Everything was working great except for one instance. If I had a majorly complex screen (one with hardly any repeating bytes) then the compression would result in hardly any savings, and sometimes would end up just a little bigger than the original! This was not good. I broke open a few of my Apple books in search of a secret or two about the hi-res screen that I may have overlooked, or simply failed to think about. And soon enough, I found something. I found out that the hi-res screen was full of "screen holes". What I mean when I say screen holes, is that the screen has many areas which are not visible to the viewer. These areas can be safely zeroed out, and these zeroed out areas will compress. So even if there is not one single repeating byte on the entire screen, after the compression it will still be smaller, not by a whole lot, but definetly smaller. Sometimes even just a few bytes help. HOW IS IT ALL ACCOMPLISHED? Let me first explain that I have uploaded the """"""""""""""""""""""""""" entire source code to the A2Pro Software Libraries. Along with this source is a complete set of utilities to load, compress, save, and decompress screens. Download file PIC.COMP10.BXY (file number 3596) if you want to have the entire source and utilities. I'll explain some of the source code here: There are two constants I use here. SCREEN is hires screen one, and BUFFER is hires screen two, which I am using to hold the compressed picture data. SCREEN equ $2000 ; screen address BUFFER equ $4000 ; crunch data buffer Here are some zero page storage variables. Picture and Data are pointers. Picture equ 0 ; picture to pack Data equ 2 ; crunch data PtrnByte1 equ $FE ; 1st pattern byte to store PtrnByte2 equ $FF ; 2nd pattern byte to store Here are the non-color and color pattern constants. Black1 = $00 ; recognition values Black2 = $80 White1 = $7F White2 = $FF Green = $2A ; color recognition values Purple = $55 Red = $AA Blue = $D5 Now here is the crunch (or compression) routine. Crunch jsr Filter ; filter screen "holes" lda #>SCREEN ; point to hires screen 1 ldx #BUFFER ; point to data buffer ldx #SCREEN ; zero out the screen holes sta Picture+1 lda #SCREEN+$2000 bne :Hole ; nope, loop for more rts ; yep, finshed *------------------------------- * Adjust screen pointer *------------------------------- * Exit, carry set if done NextPic pha inc Picture ; next picture address bne :noinc inc Picture+1 ; see if at bottom of screen :noinc lda Picture bne :nottop lda Picture+1 cmp #>SCREEN+$2000 bcc :nottop pla sec ; carry set = done rts :nottop pla clc ; carry clear, more rts *------------------------------- * Adjust data pointer *------------------------------- NextData inc Data ; next data buffer address bne :noinc inc Data+1 :noinc rts You'll notice that the first thing I do it call the Filter routine which simply fills all the screen holes with zeroes so the compression routine works effectively in all cases, regardless of the complexity of the screen. Next I set up the Picture pointer to point to hires screen one and set up the buffer to store the compressed data to hires screen two. I am only using hires screen two because it is a convienent place in memory to store the data. It could be anywhere. Then the compression loop begins at :NewByte. The next byte is loaded from the hires screen and it is checked to see if it is a $00, $80, $7F, or $FF. If the screen byte is any of these values then the program goes to the :blkwht routine which stores the color value, counts the number of color values in a row, and then stores the value as the repeating byte; then loops for more. If the screen byte is a $2A, $55, $AA, or $D5 then there is a possible pattern so the program branches to the appropriate color routine which checks the next byte to try and match a color pattern, then if a color pattern is found it counts the number of patterns in a row and stores the value as the repeating byte; then loops for more. That's it for the compression routine. Now for the decompression routine. Unpack lda #>SCREEN ; point to hires screen 1 ldx #BUFFER ; point to data buffer ldx #>> THE PROGRAMS IN THE PIC.COMP10.BXY ARCHIVE <<< """""""""""""""""""""""""""""""""""""""""""""""""""" All the programs and utilities are freeware, including the "dirty" graphics that I "quickly" drew to demonstrate my routines. PIC.COMPRESSOR - This is the main compression program. It allows you to '''''''''''''' choose and load a hi-res graphic, compress it, and then give you the option to save it and watch it decompress. Use this program to compress all your pictures. UNPACK.TEST - This program will search the CRUNCHED subdirectory and ''''''''''' load and unpack all the compressed picture files to the screen. It works like a slide show. SCREEN.HOLES - Little program I used while trying to find all those '''''''''''' screen holes. CRUNCH - This is the machine language compression and unpack '''''' routines. It does all the compressing and decompressing because of its speed. UNPACK - This is ONLY the unpack routine. If you write a program '''''' that needs to load and unpack compressed pictures, then this is all you need. You don't need the compressor because you won't be compressing pictures, you'll just unpack them. DIRECTORY STRUCTURE The way the programs are set up now, they will look """"""""""""""""""" for picture files in the subdirectory called PICS. When the compression program saves the crunched picture it will save it in the subdirectory called CRUNCHED with the extension .PCC. So every picture that you would like to crunch must be copied into the PICS subdirectory. TECHNICAL BABBLE The way the routines are set up now, the compressed """""""""""""""" picture must be loaded onto hi-res screen 2 ($4000) and it gets unpacked to hi-res screen 1 ($2000). The compressing/unpacking routines are at $7000 and $7003. After loading CRUNCH, a CALL to 28672 will compress the picture on screen 1 to screen 2 and a CALL to 28675 will unpack the compressed picture on screen 2 to screen 1. After loading UNPACK, it will reside at $7000 also, except that only one CALL is used. A CALL to 28672 will unpack the compressed picture residing on screen 2 to screen 1. SOURCE CODE The source code to the routines was written with the MERLIN """"""""""" assembler. The CRUNCH.S source and UNPACK.S source may be modified to suit your needs. You can change the compile address (ORG) to something else if you'd like the (un)compression routines to reside somewhere else in memory. You can also change the values of "Picture" and "Data" to tell the routines where to look for the compressed picture and where to uncompress the picture to. You may want to set up a "load" buffer where the compressed picture will be loaded and then unpack it to either of the hi-res screens. It's up to you. The source code is fully commented therefor I think that you will find it very interesting to browse through and read all the other technical junk as well. [*][*][*] We want your articles! If you want to write an article for GEnieLamp A2Pro, then contact the editor, A2PRO.GELAMP for more information. We pay for articles with usage credits. [*][*][*] [EOA] [HEY]////////////////////////////// HEY MISTER POSTMAN / ///////////////////////////////// Is That A Letter For Me? """""""""""""""""""""""" By Tim Buchheim [A2PRO.GELAMP] o BULLETIN BOARD HOT SPOTS o WHAT'S NEW o PROGRAMMERS' TIPS o MESSAGE SPOTLIGHT >>> BULLETIN BOARD HOT SPOTS <<< """""""""""""""""""""""""""""""""" ~ Where All the Action Is! ~ [*] CAT 2, TOP 5, MSG {59}.....Using the Merlin 8 assembler [*] CAT 2, TOP 8, MSG {43}.....Assembly language and AppleSoft BASIC [*] CAT 3, TOP 4, MSG {113}....The Merlin 16+ Assembler [*] CAT 3, TOP 19, MSG {138}....General Assembly Questions [*] CAT 11, TOP 8, MSG {111}....Programming Algorithms and Structures >>> WHAT'S NEW <<< """""""""""""""""""" ~ Announcements ~ A HALLOWEEN VISITOR BOO! """"""""""""""""""" I am sure programmers just love computer goblins (SKELETON, CAT1, TOP2, MSG:211/M530) >>> PROGRAMMERS' TIPS <<< """"""""""""""""""""""""""" ~ Helpful Advice from the Experts ~ STARTING SOURCEROR Help! My Merlin-8 manual is packed away and I cannot """""""""""""""""" remember... How do I start Sourceror? I remember the BRUN SOURCER/OBJ, but then what? (PAUL.RSM, CAT2, TOP5, MSG:59/M530) >>>>> Paul, """"" 1. Load the program to be disassembled. 2. BRUN SOURCEROR 3. Accept the $2500 (default) address for the source file. 4. Hit if the loaded program is at its "running location" Is that enough? ...John at Wood-n-Shavings _____ / \ (=====) \___+_/ !... Hans (H.HAUMANN, CAT2, TOP5, MSG:61/M530) <<<<< I found a friend's Merlin manual. After BRUN SOURCER/OBJ, enter """"" the editor. Kill the 80 column screen with Esc Ctrl-Q. Type USER. (PAUL.RSM, CAT2, TOP5, MSG:62/M530) SCROLLING TEXT I need to be able to scroll the IIe 40-column text screen """""""""""""" upwards. Does anyone have or know of a routine that can do that for me? This looks comparatively trivial to do, and I sat down to write the code, only to discover that I have nearly completely forgotten how to code 6502 assembly. Use it or lose it. I can relearn assembly, but I would rather get this project on the road =now=. TomZ (A2.TOMZ, CAT2, TOP8, MSG:43/M530) <<<<< >I need to be able to scroll the IIe 40-column text screen upwards. """"" Oops. I =meant= to say DOWNwards. It's not hard to get it to scroll upwards. TomZ (A2.TOMZ, CAT2, TOP8, MSG:44/M530) >>>>> First, I've never done this so I'm speculating, but... """"" If you want to scroll downward and back upward, as in a word processor file, then maybe you need a buffer with the text properly broken into line-length sections. Then it's a small matter to re-draw the screen by shifting pointers. I'm sure that there is a better way to do this. ;) Will you control the text content, or will it be input by the user? Charlie (A2.CHARLIE, CAT2, TOP8, MSG:45/M530) <<<<< The program would be doing all writing to the screen. This is """"" intended to be an arcade effect for an Eamon game in development. All I need is a routine that will write each line to the line below it. This was once =well= within my capabilities as an assembly user, but I haven't written a line of assembly in several years and find that I have totally lost everything I once knew on the subject. (I find this discovery to be extremely depressing, BTW) If nobody has such a routine handy, we can work around it OK. We're not even sure we want to do it that way. TomZ (A2.TOMZ, CAT2, TOP8, MSG:46/M530) >>>>> Maybe this will help... """"" First push the registers to the stack to store them so that you can restore them after you are finished. PHA TYA PHA TXA PHA You can also store any other flags, etc. that way. Next, you'll need a routine for locating the cursor. Load the x register with the horizontal cursor location, and the y register with the vertical location. Then JSR GOTOXY GOTOXY DEX ;go back one for range STX CH ;store horiz. location CH = $24 DEY ;go back one for range TYA PHA ;calculate base address LSR ; based on BASCALC ($FBC1) AND #3 ORA #4 STA BASH ;BASH = $29 PLA AND #$18 BCC :1 ADC #$7F :1 STA BASL ;BASL = $28 ASL ASL ORA BASL STA BASL RTS Next set up a counter to use to loop through the lines from 23 to 2. BEGIN LDX #1 STX HOR :HOR = $06 LDX #23 STX VER ;VER = $07 :1 LDX HOR LDY VER JSR GOTOXY LDY CH ;horiz. pos :2 LDX HOR LDA (BASL),Y ;get character on screen STA BUFFER,X ;BUFFER = $200 INC HOR INC CH LDY CH CPY #40 ;finished with line? BNE :2 LDX #1 STX HOR LDX VER INX STX VER JSR GOTOXY LDY CH :3 LDX HOR LDA BUFFER,X STA (BASL),Y INC HOR INC CH LDY CH CPY #40 BNE :3 LDX #1 STX HOR LDX VER DEX DEX STX VER CPX #1 BEQ :4 JMP :1 :4 RTS After this you will have to place the new line 1 message on line 1. Be sure to restore your registers when you are done. Hope this helps. Charlie (A2.CHARLIE, CAT2, TOP8, MSG:47/M530) >>>>> That'll get you up and running, but if you decide to go with it """"" then you'll probably want to speed it up. BTW you didn't mention if it should respect the text window or not; Charlie's routine uses the numbers for the whole screen. Todd Whitesel (A2PRO.TODDPW, CAT2, TOP8, MSG:48/M530) >>>>> Hey Tom!! """"" I wrote a blazingly fast downscroll routine for use in a project for Softdisk 8-bit, but they ceased publication and I haven't finished the program yet. The project was the ProDOS version of Electric Duet and it uses the 40-column text mode exclusively, written in 6502 opcodes so it's compatible on all Apple II's!! This is so fast because I use text screen row tables instead of computing the address. All you need to do here is make sure Top, Bottom, Left, and Right are set to the values to define the text window, normally they are setup for full screen, but this routine allows you to scroll ANY portion of the text screen! The neat thing about this routine is that after the text window is scrolled, the top line is filled with spaces. Charlies' routine looks as if it will work, but if you want speed (usually arcade style games need the fastest code possible) then try my routine! :) Have fun! - Russ P.S. If you'd rather not type this in, I'll be happy to shoot the source code file to you via attached file in email. *------------------------------------------------- * Zero page constants *------------------------------------------------- ptr equ $06 ; general usage pointer (trashable) Left equ $20 ; left margin of text window Right equ $21 ; right margin of text window Top equ $22 ; top of text window Bottom equ $23 ; bottom of text window zp equ $eb ; general zero page (trashable) *------------------------------------------------- * Downscroll *------------------------------------------------- * Entry: Top, Bottom, Left, Right set to text window Downscroll lda Bottom ; start at bottom of text window sta zp dec zp :Next_Row ldy zp ; get current row lda LOTAB,y ; set up "from" copy address sta :downmod+1 lda HITAB,y sta :downmod+2 dec zp ; get previous row address ldy zp ; set up "to" copy address lda LOTAB,y sta ptr lda HITAB,y sta ptr+1 ldy Left ; start at left of text window dey :Do_Row lda (ptr),y ; get screen byte :downmod sta $FFFF,y ; store one line down (self modified!) cpy Right ; finished row? bne :Do_Row ; nope, keep going lda Top ; at top of text window? cmp zp bne :Next_Row ; nope, do next screen row Blankline lda #" " ; fill with spaces character ldy Left ; start at left of text window :Blank sta (ptr),y ; put space there iny cpy Right ; finished row? bne :Blank ; nope, keep going rts ; ok, finished *------------------------------------------------- * Text screen line lookup table *------------------------------------------------- LOTAB hex 0080008000800080 hex 28a828a828a828a8 hex 50d050d050d050d0 HITAB hex 0404050506060707 hex 0404050506060707 hex 0404050506060707 (R.NIELSON1, CAT2, TOP8, MSG49/M530) >>>>> Use Russ' routine. :) Mine was just a quick hack to get you """"" heading in the right direction; his is good. :) Charlie (A2.CHARLIE, CAT2, TOP8, MSG:51/M530) >>>>> Here's a slightly tweaked up version of Russell's screen downscroll """"" routine that's a tad smaller, a tad faster, and missing an infinite loop bug :) Note that this uses an additional pair of zero page locations ($FE,$FF) which I've found are typically safe to grab... Also the Blankline routine is no longer externally callable. * *------------------------------------------------- * * 40 column text screen downscroller * by: Russell Nielson * Tweaks by Harold Hislop * * Downscrolls the current text _window_ * 6502 clean * *------------------------------------------------- * case se ;enable case sensitivity tr on tr adr xc off ;kill 65C02/802/816 ops org $900 ;or wherever... * *------------------------------------------------- * * Zero Page stuff(ings) * *------------------------------------------------- * ptr equ $06 ;general usage pointer (trashable) zp equ $EB ;general zero page (trashable) XtraZP equ $FE ;Russ didn't use this originally. * Left equ $20 ;left margin of text window Right equ $21 ;right margin of text window Top equ $22 ;top of text window Bottom equ $23 ;bottom of text window * *------------------------------------------------- * * Here there be code... * * Entry: Top, Bottom, Left, Right set to text window * *------------------------------------------------- * Downscroll ldx Bottom ;get bottom of current window dex ;refer to prev line * ]LnLp lda LOTAB,x ;set up the "Get" pointer sta ptr lda HITAB,x sta ptr+1 * dex ;get previous line number stx zp ;prep for 'nother pass * lda LOTAB,x ;and the "Put" ptr... sta XtraZP lda HITAB,x sta XtraZP+1 * ldy Left ;start at left of text window ]MvLp dey lda (ptr),y ;get screen byte sta (XtraZP),y ;store one line down (self modified!) cpy Right ;finished line? bne ]MvLp ;nope, so loop * ldx zp ;assume another loop needed... cpx Top ;at top of window yet? bne ]LnLp ;nope, do next screen row * lda #" " ;fill with spaces character ]Clr sta (ptr),y ;put space there dey cpy Left ;finished row? bne ]Clr ;nope, keep going rts ;ok, finished * *------------------------------------------------- * * Text screen line lookup table * *------------------------------------------------- * LOTAB hex 0080008000800080 hex 28A828A828A828A8 hex 50D050D050D050D0 * HITAB hex 0404050506060707 hex 0404050506060707 hex 0404050506060707 * *------------------------------------------------- -Harold (hope the formatting comes out Ok...) (HAROLD.H, CAT2, TOP8, MSG:51/M530) >>>>> Charlie, your quick hack was a good one! The reason I've never """"" used the BASCalc monitor routines is because I have a habit of doing everything on my own, and in my own way... just so I can customize any routine I write to do EXACTLY what I need it to do. :) (R.NIELSON1, CAT2, TOP8, MSG:53/M530) >>>>> > and missing an infinite loop bug :) """"" I KNEW IT!! Ratz! I posted that routine directly from my project code but there was a little editing that I had to do to the code here in the post. In my original downscroll routine I had certain columns of the screen that didn't get scrolled (they were data dividers) so I had the routine skip these specified columns. I edited out the column checking code from the routine and I must've done it hastily and left an infinite loop in there... thanks for spotting it and reposted a better version Harold. The reason the Blankline routine was external was because it was used by the Downscroll _and_ Upscroll routines, which saved valuable bytes in the object code, because I was running low on space. Anyway, Cool! (R.NIELSON1, CAT2, TOP8, MSG:54/M530) >>>>> Harold, """"" Sorry, but your version doesn't work. I loaded it into Merlin, assembled it, tested it, and it just fills the screen with random characters, and I can see why. :) I can see a couple of problems right away: ldy Left ;start at left of text window ]MvLp dey <====== DEY??? lda (ptr),y ;get screen byte <===== from ptr??? sta (XtraZP),y ;store one line down (self modified!) cpy Right ;finished line? bne ]MvLp ;nope, so loop You are starting at the Left margin, why would you DEY? And, you have the to pointers switched, you want to grab data from XtraZP and place at ptr. This should be: ldy Left ;start at left of text window dey ]MvLp iny lda (XtraZP),y ;get screen byte sta (ptr),y ;store one line down (self modified!) cpy Right ;finished line? bne ]MvLp ;nope, so loop Tony, here's my routine again without the infinite loop. *------------------------------------------------- * Downscroll *------------------------------------------------- * Entry: Top, Bottom, Left, Right set to text window Downscroll lda Bottom ; start at bottom of text window sta zp :Next_Row dec zp ldy zp ; get current row lda LOTAB,y ; set up "from" copy address sta :downmod+1 lda HITAB,y sta :downmod+2 dec zp ; get previous row address ldy zp ; set up "to" copy address lda LOTAB,y sta ptr lda HITAB,y sta ptr+1 ldy Left ; start at left of text window dey :Do_Row iny ; <==== this was the missing INY :) lda (ptr),y ; get screen byte :downmod sta $FFFF,y ; store one line down (self modified!) cpy Right ; finished row? bne :Do_Row ; nope, keep going lda Top ; at top of text window? cmp zp bne :Next_Row ; nope, do next screen row Blankline lda #" " ; fill with spaces character ldy Left ; start at left of text window :Blank sta (ptr),y ; put space there iny cpy Right ; finished row? bne :Blank ; nope, keep going rts ; ok, finished (R.NIELSON1, CAT2, TOP8, MSG:56/M530) >>>>> Russell, """"" >> and missing an infinite loop bug :) << I KNEW IT!! Ratz! Hehehe, I've been there too (as you proceed to point out :) Infact it seems that I'm there again... sigh. >> The reason the Blankline routine was external was because it was used >> by the Downscroll _and_ Upscroll routines, which saved valuable bytes in >> the object code, because I was running low on space. I suspected that might have been the case originally. >> You are starting at the Left margin, why would you DEY? uhm... Dyslexic Register Command Syndrome? ;-) >> And, you have the to pointers switched, you want to grab data from >> XtraZP and place at ptr. Drat! I hate making stupid errors like that... (came about when I changed your code from self modifying to zpage ptr) Speaking of "saving valuable bytes"... Using a pair of Zpage locs that are known to be expendable (instead of self modifying object) comes out several bytes smaller (and faster by a few cycles too :) The locs that are used by the monitor's RdKey routine (for the pseudo random number generator) are free for the taking if you're not making use of them anyway. [a point I often forget about, so I figure others might miss this too] Take another look at my entry code... at least I got that part right, it's tight enough to make a duck float ;-) {s quack} -Harold (HAROLD.H, CAT2, TOP8, MSG:57/M530) >>>>> Harold, using Zpage instead of self-modifying absolute only makes """"" the code faster if the loop executes just once. On most text windows, you're executing the loop upwards of 10 times, so saving cycles in the loop at the expense of the setup code is good from a speed standpoint. If you really want to crank for speed, I'd recommend two things: 1. use self-modifying absolute for both pointers This saves you 2 cycles per loop over using Zpage for both, but costs 4 in setup (1 from each ZP store changed to an absolute store). It breaks even when the window is 2 wide and wins for anything wider. 2. add "Left" to the pointers and loop from "Right-Left" down to 0 This eliminates a CPY from the loop, saving you 3 cycles times the width of the window, but costs 15 cycles in setup. It breaks even when the window is 5 wide and wins for anything wider. These changes would give you a core section that looked something like: ldx line clc lda lotab,x adc Left sta labld+1 lda hitab,x sta labld+2 lda lotab+1,x adc Left ;carry already clear, from previous ADC sta labst+1 lda hitab+1,x sta labst+2 sec lda Right sbc Left tay lp: labld: lda $FFFF,y labst: sta $FFFF,y dey bpl lp Todd Whitesel (A2PRO.TODDPW, CAT2, TOP8, MSG:58/M530) >>>>> Todd, """"" Nice explanation of execution cycle time and setup/overhead time. Cool example too. :) (R.NIELSON1, CAT2, TOP8, MSG:59/M530) >>>>> I may be off base here, but assuming you have an enhanced //e can't """"" you turn on the enhanced video firmware (PR#3), issue a CNTL-Q for 40 column screen and use the CNTL-V to scroll down and CNTL-W to scroll up?? It's been a long time since I played with this but the information is in the looseleaf "About Your Enhanced Apple IIe: Programmer's Guide" manual that came with the //e Enhancement kit. Bob, AF6C (R.ECKWEILER, CAT2, TOP8, MSG:61/M530) RESIZING YOUR STACK Hi Assembly Gurus: """"""""""""""""""" I have written a couple of CDAs (in Merlin 16+); then I wrote a memory query utility for GNO/ME THEN I obtained a pre-written GNO/ME mem util (written in C). Using these I found that I am using 65%+ of stack under GNO/ME and my CDAs are using 4K each. Now the question ... under assembly programs like Merlin 16+, how do I control the allocated stack size. Ok, how do I do it under ORCA/M as well!!! The pragma stacksize give me control under ORCA/C. The Assembly manuals (Merlin and ORCA/M) mention the defaults BUT not how to change them. Thanks in advance! Doug M. (D.MITTON, CAT3, TOP4, MSG:113/M530) >>>>> You override the GS/OS default stack size of 4k by linking a stack """"" segment into your program. I don't know how to create a stack segment, though. for more information about stack/direct-page segments, see pages 38-39 and 476-477 in the _GS/OS Reference_. (A2PRO.GELAMP, CAT3, TOP4, MSG:114/M530) >>>>> Doug, """"" Here is a piece of code that explains what I've been able to do. ************************************************** * * * Linker command file * * * ************************************************** typ TOL lkv 2 asm stuff.s asm dp.s lnk stuff.l sav stuff knd $12 ;"direct-page/stack" object segment as mentioned ;in Apple IIGS GS/OS Reference manual. Page 37. lnk dp.l sav dp Next file ************************************************** * * * Direct page space * * * ************************************************** typ TOL rel ds $200 ;Makes 2 pages of direct page space sav dp.L ************************************************** Next file ************************************************** * * * Stuff program * * * ************************************************** type TOL rel ;stuff's stuff sav stuff.L ************************************************** Clay Warning! Opinions will change due to new facts. Clayburn W. Juniel, III - Effective Software Solutions clay1@primenet.com (C.JUNIEL, CAT3, TOP4, MSG:115/M530) >>>>> And, since you asked, it's pretty much the same under ORCA/M. The """"" details are in the manual; see the KIND directive on page 328 and the various kind fields on page 490. You can also do a lot more than just create a stack segment, and I suspect Merlin can, too. And now, back to our regularly featured assembler... Mike Westerfield (BYTEWORKS, CAT3, TOP4, MSG:116/M530) >>>>> Thanks for the information on creating a DP segment in Merlin 16+ """"" (and ORCA/M), it was exactly what I was looking for. One additional point to any other interested parties, make sure you are using Linker.XL (lkv 2) for the previous examples to work. My installation defaulted to Linker.GS which was perfect for my CDAs and ProDOS8 stuff but not for this. ORCA/M was a little more straight forward to implement once I figured out what was going on BUT I still don't think I would have gotten either out of the manual(s). (I know, they are for reference, not tutorial!!!! :-)) Thanks Again!!! Doug M. (D.MITTON, CAT3, TOP4, MSG:117/M530) LINEAR REGRESSION Mike W, """"""""""""""""" I'd like to duplicate the curve fit function used by Quick Click Calc in a small project. On p. 51 of the QCC manual, you give the equation for the first, second, and third order fits. The third order fit is given as: 2 3 y = A + Bx + Cx + Dx This looks a lot like a cubic polynomial expression for a spline function (although the examples I've seen reverse the order of the terms). If this is a spline function, then what basis matrix are you using? If not, what are the A B C and D coefficients? But the manual mentions that this is a "linear regression"--a term I haven't heard of before. Worse, I can't find it in any of my books, including a fairly recent college Algebra & Trig textbook. Is it safe to assume that the coefficients are the dataset's y-values i, i+1, i+2, and i+3? Can you help me out? Michael (ANIMASIA, CAT11, TOP8, MSG:111/M530) >>>>> Hi Michael, """"" Linear regression is a pretty standard method for finding coefficients yielding the smallest error between a curve fit and a set of data points. I could cite a gob of sources, but most of the books I learned from (and still use) are 20 years old, so you might have trouble finding them. Try looking through any halfway decent college probability & statistics text, vurtually any data analysis book for the physical sciences, or a linear algebra text that is engineering oriented, rather than oriented towards theoretical mathematics. I'll try to give you a quick version here, but do try to find the books-- among other things, they will tell you how to figure the error in the fit! You basically create two matrices. One is a cube; it has the sum of the independent variable (x in most notations) raised to various powers. The power starts at 0 in the top left position, and you add one across the top row and left column. The power for the interior values is the sum of the power to the top and left. So, showing only the powers in the correct spot, the cubic array looks like this (ASCII is a pain for matrices with powers; write it on a sheet of paper :) 0 1 2 3 4 ... 1 2 3 4 5 2 3 4 5 6 3 4 5 6 7 4 5 6 7 8 You can keep going as long as you like. The matrix I've shown is for a 4th order polynomial fit. To actually calculate the terms, you sum the values raised to the power I've shown. Since I can't use mathematical notation, I'll use Pascal. :) In this case, all of the values are stored in two arrays, x[size] and y[size]. So to compute the value for 4 in the array, you would sum all of the x values raised to the 4th power, like this: s4 := 0.0; for i := 1 to size do s4 := s4 + sqr(sqr(x[i])); The second array is a column (or a vector). It's the sum of the dependent variable times a power of the independent variable. The powers for the independent variable are the same as for the left column of the square matrix. Calculating the third term down would go something like this: sy2 := 0.0; for i := 1 to size do sy2 := sy2 + y[i]*sqr(x[i]); There is a third matrix; it contains the coefficients for the polinomial. From the manual, that's A, B, C, etc. It's a column, too, just like the second one. The last step is to combine these equations into a matrix equality. Calling the square one S, the coefficients c, and the second matrix with the x and y powers n, the equation is Sc = n You solve this set of simultaneous equations for the coefficients. For higher or lower order polinomials, simply adjust the size of the matrices. CAUTION: The equations are not well behaved. You can get numerical '''''''' errors, like divide by zero, with many off the shelf equation solvers. Guard for that! Finally, if this didn't make much sense, rest assured that it's a lot easier with a blackboard or book, where you can use matrix notation, powers, and summation signs. :) If this confused you, find a discussion in a book. Mike Westerfield (BYTEWORKS, CAT11, TOP8, MSG:112/M530) <<<<< Mike-- """"" Excellent overview! I actually understood your ASCII power notation matrice and your Pascal sources, which is not surprising because I remember your Call -APPLE articles being so well written. I feel I have a much better idea of what I have to work towards than before. However, I still don't see how the three matrices relate to eachother to produce the results that they do. So it looks like I'm going to stop at the university library tomorrow to investiage your sources; "data analysis for physcial sciences" sounds like a good bet. I'll let you know how it works out. Thank you! Michael (ANIMASIA, CAT11, TOP8, MSG:113/M530) >>>>> Hi Michael, """"" If you got everything but how to solve the matrix equation, concentrate on linear algebra books. In fact, you might even want to find one of those encyclopedia sized books on engineering mathematics that I assume are still used to cover 4-6 math courses in an engineering curriculum. Concetrate on simultaneous solutions to multiple equations, which is what you are actually doing. Once you get to the point where you're actually doing it, switch to a good introductory text on numerical analysis, or check out something like Sedgewick's Algorithms book. All will have better methods for actually solving the matrix equations than the math books are likely to show, since the methods that work well on a computer are a little different from the ones that work well by hand. Mike Westerfield (BYTEWORKS, CAT11, TOP8, MSG:114/M530) <<<<< Mike, """"" I spent the better part of the day at the library looking through the types of books you suggested. You were right; there are tons of books which cover linear regression in many different fields. Some good. Some bad. I backtracked and began investigating how to find the closest fit to a first order function and even that slowed me down. Not surprisingly, I found myself having to relearn much of the matrix operations for solving simultaneous solutions. So it looks like I'll have to go back and start from the beginning. I'll check into "Sedgewick's Algorithms" too. Still, I'm enjoying this because it's no longer abstract theory. Michael (ANIMASIA, CAT11, TOP8, MSG:115/M530) >>>>> Cool. FWIW, linear regression was the first thing I ever did with """"" a matrix (back in high school) and it remains one of the most-used, and IMHO, most usefull things I've ever done with a matrix. :) And in physics and math, I've seen quite a few matricies. Mike Westerfield (BYTEWORKS, CAT11, TOP8, MSG:116/M530) >>>>> One book that covers this subject fairly well is _Advanced """"" Engineering Mathematics_ by Erwin Kreyszig. It's an older college text book (1964 - fourth edition) but should be able to be found in used book stores. What I like about this book is that it contains a lot of practical examples instead of just dry theory. Another book that may be of interest is "BASIC Computer Programs in Science and Engineering" by Jules Gilder 1980 (A Hayden PaperBack). It is full of BASIC programs. Chapter 4 is "Matrix Mathematics" and Chapter 5 is "Data Analysis" including linear a least-squares fit and various logarithmic least-squares fit programs In the seventies and early eighties I wrote many programs on a Tektronix 4054 desktop computer. It had built-in matrix functions and you could solve multiple equations with multiple unknowns with one BASIC call. Bob, AF6C (R.ECKWEILER, CAT11, TOP8, MSG:117/M530) BEZIER CURVES Speaking of least-squares fit algorithms, I once had an """"""""""""" interest in how Bezier curves were drawn. You know, a spline curve where the points can be unordered in both the X and Y axes. I wanted to, given a completely random set of points, draw a smooth curve through the points. Best I ever came up with was limited. The method would only work if the X (or Y) coordinates were listed in order (increasing or decreasing). Does anyone know how these are computed? I know it can be done, because I've seen it in some paint/draw programs. ...Chris (K.FLYNN, CAT11, TOP8, MSG:120/M530) >>>>> Chris, """"" Bezier curves are pretty easy to draw once you know how it's done. The simplest Bezier curve has four points: two endpoints and two handle points which define the shape of the curve. Image that the following four points will create a smooth Bezier curve. ep is endpoint and hp is handle point. hp1 ep1 ep2 hp2 When a Bezier curve is drawn, the drawing algorithm starts drawing from the first endpoint, ep1, toward the first handle point, hp1, but never actually touches hp1 because as it goes along, it begins to head toward the next handle point, hp2. Again, the curve doesn't touch hp2 because it heads toward the last endpoint, ep2. The curve therefore touches the endpoints but only heads toward the handle points. The handle points are called handles because if you drag these handles around, you'll change the shape of the curve. These are the curves that Postscript uses for its foundation; same for most any illustration program. There are two ways you can draw a Bezier curve. The first is to say that a variable t will be increased from 0 to 1 over series of steps and a basis matrice function will be solved for x and y with t. You simply connect the x and y's as you increment t. This is slow and entirely too precise for drawing on the screen. The second way is much faster because it recursively splits the Bezier curve into two smaller Bezier curves until the curves become straight enough to be approximated by lines. This only uses shifts and adds and you'll find the source code to this below. Still, you wanted to know how to connect a whole series of points. That's easy too. To lengthen a Bezier curve, add three more points: two handles and an endpoint. Because the last endpoint of the first Bezier is the first endpoint of the second Bezier, that endpoint is reused. So you need to have "(curves * 3) + 1" points. Another thing to keep in mind is that to have the overall Bezier curve look smooth between adjacent sub-curves requires you to position the two handles on either side of an endpoint to line up in a straight line across the endpoint. Otherwise, you'll have a sharp bend in your curve, (which may be what you want too). However, this won't _completely_ solve your problem because you specificially wanted to have this curve pass through _all_ of your points. Well, a Bezier curve, like I mentioned, only passes through the endpoints but not the handles. There are different types of curves, and the one you would want to use to pass through all points is a Catmull-Rom curve, which are harder to draw than Bezier curves because you can't as easily subdivide them. But don't let that discourage you because Bezier curves are great and if you can get them to work (no problem) you're on your way to creating an illustration program for the GS :) Michael (This C source code is old and doesn't use the bit shift operator to divide by two. This is because I assumed there was a problem with the way Orca/C generated code if it tried to bit shift a negative number. I wanted to use negatives because I wanted to have a Cartesian coordinate plane, but this could easily be solved if you use only the positve quadrant of the plane, such as screen coordinates. Also, it refers to endpoints as control points.) #include #include #define BezDepth 4 /* greater the depth, the smoother the curve */ #define NumBezPts 17 /* must be >= 2^BezDepth + 1 */ /* It's important to note that increasing BezDepth makes smoother curves--up to a point. We reach diminishing returns in increasing BezDepth too much, since the accumulated error of repeated averaging eventually throws the calculations off by one or more pixels. This could be soved by using fixed point math. */ typedef struct {int top, left, bottom, right;} rect2, *rect2ptr; typedef struct {int x, y;} intVector2, intPoint2, *intVector2ptr, *intPoint2ptr; intPoint2 bezPts [NumBezPts]; intPoint2ptr bezPtsPtr; int xCenter, yCenter; void SubdivideBezier (intPoint2 p0, intPoint2 p1, intPoint2 p2, intPoint2 p3, int depth); void DrawBezier (intPoint2 ctrl1, intPoint2 hand1, intPoint2 hand2, intPoint2 ctrl2); void main (void) { rect2 viewPort; intPoint2 ctrl1, hand1, hand2, ctrl2; /* Define Bezier curve's points: */ ctrl1.x = -100; ctrl1.y = 0; /* Cartesian coordinates */ hand1.x = -30; hand1.y = 60; hand2.x = 10; hand2.y = -80; ctrl2.x = 100; ctrl2.y = 0; GetPortRect ((RectPtr) &viewPort); xCenter = (viewPort.left + viewPort.right) / 2; yCenter = (viewPort.top + viewPort.bottom) / 2; SetPenSize (2, 1); SetPenMode (modeCopy); SetSolidPenPat (0); DrawBezier (ctrl1, hand1, hand2, ctrl2); /* Draw handles as dots: */ MoveTo (hand1.x + xCenter, yCenter - hand1.y); LineTo (hand1.x + xCenter, yCenter - hand1.y); MoveTo (hand2.x + xCenter, yCenter - hand2.y); LineTo (hand2.x + xCenter, yCenter - hand2.y); } void DrawBezier (intPoint2 ctrl1, intPoint2 hand1, intPoint2 hand2, intPoint2 ctrl2) { int i; bezPtsPtr = bezPts; *bezPtsPtr++ = ctrl1; SubdivideBezier (ctrl1, hand1, hand2, ctrl2, BezDepth); MoveTo (bezPts [0].x + xCenter, yCenter - bezPts [0].y); for (i = 1; i < NumBezPts; i++) LineTo (bezPts [i].x + xCenter, yCenter - bezPts [i].y); } void SubdivideBezier (intPoint2 p0, intPoint2 p1, intPoint2 p2, intPoint2 p3, int depth) { intPoint2 q0, q1, q2, r0, r1, s0; int x, y; if (!depth) { *bezPtsPtr++ = p3; return; } q0.x = (p0.x + p1.x) / 2; q0.y = (p0.y + p1.y) / 2; x = q0.x; y = q0.y; q1.x = (p1.x + p2.x) / 2; q1.y = (p1.y + p2.y) / 2; x = q1.x; y = q1.y; q2.x = (p2.x + p3.x) / 2; q2.y = (p2.y + p3.y) / 2; x = q2.x; y = q2.y; r0.x = (q0.x + q1.x) / 2; r0.y = (q0.y + q1.y) / 2; x = r0.x; y = r0.y; r1.x = (q1.x + q2.x) / 2; r1.y = (q1.y + q2.y) / 2; x = r1.x; y = r1.y; s0.x = (r0.x + r1.x) / 2; s0.y = (r0.y + r1.y) / 2; x = s0.x; y = s0.y; SubdivideBezier (p0, q0, r0, s0, --depth); /* subdivide into left half */ SubdivideBezier (s0, r1, q2, p3, depth); /* subdivide into right half */ } (ANIMASIA, CAT11, TOP8, MSG:121/M530) >>>>> Oh yeah. I forgot to mention that to compile and use the code you """"" can use Prizm's Graphics Output window. Just open that window and choose Compile to Memory. It's best to make the Graphics Output window as big as it can be (Mike- the zoom box on that window doesn't do anything.) Also, the curve won't look stunningly smooth because of the accumulated division error inherent in integer math. You'll need to use fixed-point math to get perfectly smooth curves. Michael (ANIMASIA, CAT11, TOP8, MSG:122/M530) >>> MESSAGE SPOTLIGHT <<< """"""""""""""""""""""""""" ~ Important or Interesting Messages ~ 65816 IN AN ATARI? Greetings! I've got a 65816 transplanted into my """""""""""""""""" 8-bit Atari (please no flames) and was searching here for some 65816 assembler examples. This seems to be the biggest collection of '816 programmers on GEnie; what can you point to? I've programmed for over 10 years on the 6502, and was looking for fast signed multiply routines, etc. Also, since everything here is ".BXY", can anyone suggest a path to some other archive format like ARC or LZH? Thanks in advance... (JDPOTTER, CAT3, TOP19, MSG:138/M530) >>>>> JDPOTTER, """"" >> I've got a 65816 transplanted into my 8-bit Atari (please no flames) and >> was searching here for some 65816 assembler examples. Hey, no flames from me! How did you get the 816 in the Atari anyway? (by leaving pin 1 out of the socket?? That's what I did on my IIc, works great! :)) Most likely most of the source you'll find here for 816's will be for the Apple IIgs, which won't do you tooo much good... (the IIgs has a "toolbox" (part rom, part in the OS) that covers a =lot= of ground... math routines included.) >> Also, since everything here is ".BXY", can anyone suggest a path to some >> other archive format like ARC or LZH? Thanks in advance... Chances are if some file or other (or more than one :) sounds like a likely candidate for what you're looking for it could be unpacked by one of the folks around here and either emailed to you that way, or maybe packed up using another method... (I think there's a utility around somewheres for producing ARC files on an Apple II) -Harold (HAROLD.H, CAT3, TOP19, MSG:139/M530) >>>>> There's also a MS-DOS utility to unpack .BXY and .SHK archives """"" (both ShrinkIt archives), if that's of any help to you. Doug "As Canadian as possible under the circumstances."--Heather Scott (EDITOR.A2, CAT3, TOP19, MSG:140/M530) >>>>> There are some fast math routines for signed and insigned 2, 4 and """"" 8 byte integer math in the ORCA/M package. The source code is available separately as GS-13 ORCA/Sublib Source $25, available from Byte Works. The files are ASCII files with the SRC file type stamp. The biggest problem you would face is getting the files from the Apple IIGS 3.5" disk they ship on to your computer. A friend with an Apple ][ or Mac can help. If you're interested, let me know. I can send you a catalog; you can at least get an idea what we have. I'll need your mailing address if you want the catalog. Mike Westerfield (BYTEWORKS, CAT3, TOP19, MSG:141/M530) <<<<< Harold.H, I got the 65816 from the guy who bought the rights to all """"" ICD Atari 8-bit products. It's the 65C816 and a PAL mounted in a socket, plugs directly into my 6502 socket. I saw some interesting code tips in the "Optomeisters" topic. I'm really looking for a 16 x 16 -> 32 bit signed multiply; I was able to adapt some of their fast routines, but would like to see more. Thanks. Jeff (JDPOTTER, CAT3, TOP19, MSG:142/M530) >>>>> Jeff, """"" > I'm really looking for a 16 x 16 -> 32 bit signed multiply You might want to check out the "Apple Assembly Lines" archives in the libraries. They have some _excellent_ articles w/source on all sorts of algorithms such as various sized multiples. (They even have a 8 x 8 -> 16 bit multiply that executes in 65 cycles!) Search on "AAL" for all the issues, or "multiply" or "multiplication" for the ones you need. Michael (ANIMASIA, CAT3, TOP19, MSG:143/M530) [*][*][*] While on GEnie, do you spend most of your time downloading files? If so, you may be missing out some excellent information in the Bulletin Board area. The messages listed above only scratch the surface of what's available and waiting for you in the bulletin board area. If you are serious about your Apple II, the GEnieLamp staff strongly urges you to give the bulletin board area a try. There are literally thousands of messages posted from people like you from around the world. [*][*][*] [EOA] [DEV]////////////////////////////// DEVELOPER'S CORNER / ///////////////////////////////// News From The A2Pro Online Developers """"""""""""""""""""""""""""""""""""" By Tim Buchheim [A2PRO.GELAMP] o ONLINE SUPPORT IN A2Pro o EDIT-16 SUPPORT o USING THE GNO SHELL o THE SPLAT! SOURCE LEVEL DEBUGGER >>> ONLINE SUPPORT IN A2Pro <<< """"""""""""""""""""""""""""""" CAT TOP COMPANY === === ======= 29 INDEPENDENT DEVELOPERS ONLINE 2 DYA/DigiSoft Innovations Online 8 Simplexity Software Online 14 Quality Computers Q-LABS Online 20 DreamWorld Software Online 26 METAL/FV Software Online 32 Kitchen Sink Software Online 38 EdIt-16 (Bill Tudor) 30 PROCYON, INC. 31 SOFTDISK PUBLISHING 33 GS+ MAGAZINE 34 JEM SOFTWARE 35 PRODEV, INC. 36 THE BYTE WORKS Each month this column feature highlights and news from various developers who provide support via A2Pro. >>> EDIT-16 SUPPORT <<< """"""""""""""""""""""""" EDIT-16 REQUEST Bill, """"""""""""""" Is there anything new to report about Edit-16 or are no more updates planned? My only real desire is to have it handle files larger than 64k. Other than that, I can't think of a thing. And if no further improvements are planned, I can understand that. Bob (R.FISCHER7, CAT29, TOP38, MSG:108/M530) >>> USING THE GNO SHELL <<< """"""""""""""""""""""""""""" SWITCHING PROCESSES How do you switch processes in GNO? I've found the """"""""""""""""""" GNO shell to be very confusing. Is Edit-16 compatible? I haven't been able to get it to work with the shell yet. Any help would be appreciated! Brian Gillespie, Jaunt! Software (B.GILLESPIE3, CAT30, TOP2, MSG:193/M530) <<<<< I've learned some more about switching processes, but how do you """"" switch out of the ORCA editor? It eats the Control-Z keypress. Thanks! Brian Gillespie, Jaunt! Software (B.GILLESPIE3, CAT30, TOP2, MSG:194/M530) >>>>> You need to set the auxtype of the ORCA editor to something (I """"" think $DC00 but it should be in the GNO docs somewhere, so don't trust me, trust them) to tell GNO it needs to handle the input stuff differently. Maybe someone else here can tell us just what it does differently? Todd Whitesel (A2PRO.TODDPW, CAT30, TOP2, MSG:196/M530) >>>>> From the GNO Shell User's Manual (Appendix E, Non-Compliant """"" applications, page 50): "Setting the auxtype of an application to $DC00 disables the interrupt driven keyboard buffering and turns off the GNO/ME cursor. Desktop programs use the GNO/ME keyboard I/O via the Event Manager, and thus should NOT have their auxtype changed." However, I always thought EXE (and S16) files were supposed to follow the FTN that details the $DBxx auxtype. The ORCA editor has an auxtype of $DB01 (at least mine does.) - Tony (A2.TONY, CAT30, TOP2, MSG:197/M530) >>>>> >However, I always thought that EXE (and S16) files were supposed """"" >to follow the FTN that details the $DBxx auxtype. They are. :) But when you use a S16 or EXE program in GNO, it is being loaded and executed by GNO itself with direct calls to the System Loader toolset.. Only _QuitGS looks for that $DBxx in the auxtype.. since GNO isn't loading the program through _QuitGS, it can require the auxtype to be whatever it needs. (I assume that it properly handles the defined bits in a $DBxx auxtype, though.) Note that GNO doesn't require any weird auxtypes for desktop programs.. so leave them set to whatever is appropriate for the specific app. (A2PRO.GELAMP, CAT30, TOP2, MSG:198/M530) >>>>> > Only _QuitGS looks for that $DBxx in the auxtype.. """"" Okay, so there's no harm in changing EXE auxtypes for files that run on a shell from $DB01 to $DC00 (ie. the ORCA editor.) However, I wouldn't want to change a S16 auxtype like that unless I only plan on running the program from the shell, right? - Tony (A2.TONY, CAT30, TOP2, MSG:199/M530) >>>>> right, although I would assume that most S16 programs you use """"" aren't text programs, and therefore wouldn't need any auxtype changes. (Programs that use the Event Manager, such as desktop programs, work fine in GNO, from what I understand.. but I don't have GNO, so I can't be sure. :) (A2PRO.GELAMP, CAT30, TOP2, MSG:200/M530) >>>>> You can't change the auxtype of a S16 file to $DC00 if the file is """"" on an HFS volume, due to the way the HFS FST maps between ProDOS and HFS types. (At least, not the standard GS/OS way. Don't know if you can get around it by mucking with the optionList.) (S.REEVES2, CAT30, TOP2, MSG:202/M530) >>>>> huh? why can't you change the auxtype of a S16 file on an HFS """"" volume? A S16 file with an auxtype of $DC00 would have a creator type of "pdos" and a file type of "p" $B3 $DC $00 (A2PRO.GELAMP, CAT30, TOP2, MSG:203/M530) >>>>> The HFS FST won't preserve a non-zero auxtype of a S16 file unless """"" it starts with $DB (this is described on page 334 of the Programmer's Reference for System 6.0). It seems you can set it to $DC00 by directly changing the Mac filetype to "p" $B3 $DC $00 (via the optionList), but you must do this manually. GNO's standard chtyp command won't do it for you. (S.REEVES2, CA30, TOP2, MSG:204/M530) >>>>> yuck. that's stupid. :( """"" (A2PRO.GELAMP, CAT30, TOP2, MSG:205/M530) >>> THE SPLAT! SOURCE LEVEL DEBUGGER <<< """""""""""""""""""""""""""""""""""""""""" USING SPLAT! Hi, I have two questions related to Splat! """""""""""" 1.) I have searched the manual cover to cover trying to figure out how to display strings in hex in the variables window/dialog a la the 'mem' command does in the ORCA debugger. I am manipulating text, control characters and NULL's in char arrays and would like to see the changes in hex while stepping through the program. Can I do this with Splat!? Currently I am using Splat! for debugging program control but switch over to ORCA debugger to watch the changes in the arrays because I can only get the ascii text in double quotes using Splat!. Which brings me to question 2. 2.) Are there any known problems having Splat! and ORCA debugger in the ORCA shell at the same time. So far I haven't noticed any problems but I would like to know ahead of time what to watch out for. My setup has the 'shell' version of Splat! installed in ORCA/shell 2.x, and the ORCA/Debugger init and debugger utilities installed. I use a script to run ORCA/D. I 'cmpl +d {program}.cc keep={program}' once, and type 'splat {program}' to use Splat! or 'debug {program}' to use the ORCA/D. This, so far, works ok (my programs are ANSI C, text display only, no toolbox) but I prefer Splat!'s interface to ORCA/D's and want to save the hassle of jumping from one to the other. Thanx. Eric Heim (of course, by using both there is no spent money wasted :) (E.HEIM3, CAT30, TOP9, MSG:31/M530) >>>>> Eric, """"" I'm not familiar with Orca/Debugger's mem command, but I'm afraid you can't do what you're asking for (showing characters as hex) in Splat! at this time. I believe unprintable characters show up either as octal or hex (it's been a while since I've used it much) but I know that's not what you're after. I don't know imagine there would be any problems with the setup you are running (Orca INIT and Splat! shell version), but it's not something that I've ever tested and certainly don't guarantee. If it works, then it works. And until there's a major upgrade to Splat! (don't ask), I guess you'll have to continue to use both to get what you want. Sorry. Mike Hackett (M.HACKETT, CAT30, TOP9, MSG:32/M530) <<<<< Hi Mike H., """"" Don't be sorry, Splat! is great. ORCA/Debugger is great. I'm glad I have both. I was just hoping that Splat! had EVERYTHING to save a little time while trying to fix my latest 'index past the end of array' ;-) Eric Heim (E.HEIM3, CAT30, TOP9, MSG:33/M530) >>>>> Eric, """"" > display strings in hex in the variables Well it *is* possible, but it doesn't look pretty... Here is a way to see 4 characters in hex from a string. The text characters are stored in a pointer that doesn't really point to anything. Pointers are displayed in their hex values. The hex values can also be displayed in the output window. Look at BadAddress to see the 4 chars displayed in hex, not what it points to. It doesn't really point anywhere.:) #pragma keep "Program" #pragma debug -1 #include #include struct StringPlus { char SPlus[10]; }; void main (void) { struct StringPlus ASP; unsigned int x; /* Declare address and set to unique numbers */ unsigned char *BadAddress; asm { lda #0xFFFF sta BadAddress+2 lda #0xFFFF sta BadAddress } strcpy(ASP.SPlus, "5678\n"); ASP.SPlus[6] = 0; for(x=0;x<10;x++) { /* Notice ordering to keep string characters lined up */ /* Copy string characters to the hex address for hex display */ asm { lda ASP sep #0x20 sta BadAddress+3 rep #0x20 } asm { ldx #1 lda ASP,x sep #0x20 sta BadAddress+2 rep #0x20 } asm { ldx #2 lda ASP,x sep #0x20 sta BadAddress+1 rep #0x20 } asm { ldx #3 lda ASP,x sep #0x20 sta BadAddress rep #0x20 } /* Increment string chars for viewing change */ ASP.SPlus[0]++; ASP.SPlus[1]++; ASP.SPlus[2]++; ASP.SPlus[3]++; /* Display some of string in hex in output window */ printf(" Hex=%X, %X\n", ASP.SPlus[0], ASP.SPlus[2]); } exit(0); } More chars can be copied into more hex addresses for display, but this can be used to view some important ones. - James - [IMAGE] (J.GRAY38, CAT30, TOP9, MSG:34/M530) <<<<< James, """"" Thanx for your reply. Actually, my interest in looking at the hex in the string was purely for debugging purposes. This particular function is a filter for raw data and somehow (thanks to Splat! and ORCA/Debugger I found the problem) it was indexing past the end of an array under certain conditions. The array is part of a structure and the next element was a pointer that would get blasted when the indexing went too far. Easy to fix once I saw what was happening :) Eric Heim (E.HEIM3, CAT30, TOP9, MSG:35/M530) [EOA] [LIB]////////////////////////////// LIBRARY BIT BONANZA / ///////////////////////////////// HOT Files You Can Download """""""""""""""""""""""""" By Tim Buchheim [A2PRO.GELAMP] o GREAT NEW FILES! >>> GREAT NEW FILES! <<< """""""""""""""""""""""""" File #4871 MTL.PUB.SRC.BXY (ALL) Uploaded on 10/28/95 by JUST.DAVE About 124K (d/l time approx. 9 minutes @ 2400 baud) This file is part of the release of METAL v1.09.07. It contains the source code that was released with METAL v1.09.07. Read MTL7.README.TXT (file #25957) in the A2 library for details. File #4870 FOREACH.BXY (GS) Uploaded on 10/19/95 by S.REEVES2 About 13K (d/l time approx. 1 minute @ 2400 baud) This is a version of the UNIX shells' built-in "foreach" construction, for iterating a series of commands over different values of a variable. It was written by Sean McAfee (mcafee@umich.edu). Requires an Apple IIgs and GNO 2.0 or higher (works with ORCA/Shell 2.0 too, but ORCA already has an equivalent command). File #4868 REZTHINGY.BXY V1.0B2 (GS) Uploaded on 10/15/95 by B.WELLS5 About 5K (d/l time under 1 minute @ 2400 baud) This Spectrum script will allow you to name resources in your REZ source code and then run the script to generate all the rName resources for each 'named' resource. Cool, eh? :) This is just a very quick hack, so the only documentation is what appears when you run the script. An example REZ file is also included. File #4867 HTMLEDIT.BXY (GS) Uploaded on 10/14/95 by C.STILES3 About 81K (d/l time approx. 5 minutes @ 2400 baud) Obtained from the Internet - source is Nova Scotia user group. See the description on A2 for more info, or just donload it and extract the info. Promotes the use of HTML. No doc file, but help button is available. File #4864 PRSET1.0B1.BXY (GS) Uploaded on 10/1/95 by R.ECKWEILER About 19K (d/l time approx. 1 minute @ 2400 baud) PRSet is an ORCA utility that allows configuring the .PRINTER driver directly from the ORCA command line or from an exec file. By putting a PRSET command in the LOGIN file for ORCA the printer may be configured automatically each time ORCA is run. The program allows you to set all the parameters normally set by the CDA or CDEV programs and has extensive printer initialization string inputting capabilities. [EOA] [LOG]/////////////////////////////// LOG OFF // ////////////////////////////////// GEnieLamp Information """"""""""""""""""""" o COMMENTS: Contacting GEnieLamp o GEnieLamp STAFF: Who Are We? GEnieLamp Information GEnieLamp is published on the 1st of every month """"""""""""""""""""" on GEnie page 515. You can also find GEnieLamp on the main menus in the following computing RoundTables. RoundTable Keyword GEnie Page RoundTable Keyword GEnie Page """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" DigiPub DIGIPUB 1395 Atari ST ST 475 Macintosh MAC 605 IBM PC IBMPC 615 Apple II A2 645 Apple II Dev. A2PRO 530 Macintosh Dev. MACPRO 480 Geoworks GEOWORKS 1050 BBS BBS 610 CE Software CESOFTWARE 1005 Mini/Mainframe MAINFRAME 1145 Programming PROGRAMMING 1445 Data Comm. DATACOMM 1450 IBM PC Prog IBMPCPRO 617 PowerPC PPC 1435 PowerPCProg PPCPRO 1440 GEnieLamp is also distributed on CrossNet and many public and commercial BBS systems worldwide. o To reach GEnieLamp on Internet send mail to genielamp@genie.com o Back issues of GEnieLamp are available in the DigiPub RoundTable Library #2 on page 1395 (M1395;3). Internet users should use the GEnie gopher (gopher.genie.com) which has most back issues (but might be missing a few of them). After you connect to gopher.genie.com, choose the "Magazines and newsletters" item and then choose the menu item for the Apple II. o GEnieLamp pays for articles submitted and published with online GEnie credit time. Upload submissions in ASCII format to library #31 in the DigiPub RoundTable on page 1395 (M1395;3) or Email it to GENIELAMP. On Internet send it to: genielamp@genie.com o We welcome and respond to all E-Mail. To leave comments, suggestions or just to say hi, you can contact us in the DigiPub RoundTable (M1395) or send GE Mail to John Peters at [GENIELAMP] on page 200. o If you would like to meet the GEnieLamp staff "live" we meet every Wednesday night in the Digi*Pub Real-Time Conference at 9:00 EDT (M1395;2). o The Digital Publishing RoundTable is for people who are interested in pursuing publication of their work electronically on GEnie or via disk-based media. For those looking for online publications, the DigiPub Software Libraries offer online magazines, newsletters, short-stories, poetry and other various text oriented articles for downloading to your computer. Also available are writers' tools and 'Hyper-utilties' for text presentation on most computer systems. In the DigiPub Bulletin Board you can converse with people in the digital publishing industry, meet editors from some of the top electronic publications and get hints and tips on how to go about publishing your own digital book. The DigiPub RoundTable is the official online service for the Digital Publishing Association. To get there type DIGIPUB or M1395 at any GEnie prompt. >>> GEnieLamp STAFF <<< """"""""""""""""""""""" GEnieLamp o John Peters [GENIELAMP] Publisher """"""""" o Mike White [MWHITE] Managing Editor APPLE II o Doug Cuff [EDITOR.A2] EDITOR """""""" o Ray Pasold [R.PASOLD] A2 Staff Writer o Charlie Hartley [A2.CHARLIE] A2 Staff Writer A2Pro o Tim Buchheim [A2PRO.GELAMP] EDITOR """"" ATARI o Sheldon H. Winick [GELAMP.ST] ATARI EDITOR """"" o Bruce Smith [B.SMITH123] EDITOR/TX2 o Mel Motogawa [M.MOTOGAWA] Atari Staff Writer o Richard Brown [R.BROWN30] Atari Staff Writer o Al Fasoldt [A.FASOLDT] Atari Staff Writer o Timothy V. Steed [T.STEED1] Atari Staff Writer o Lloyd E. Pulley [LEPULLEY] Atari Staff Writer IBM o Sharon La Gue [SHARON.LAMP] IBM EDITOR """ o Tika Carr [LAMP.MM] MULTIMEDIA EDITOR o Susan M. English [S.ENGLISH1] Multimedia Graphics Artist o Wayne & Chris Ketner[C.KETNER] IBM Staff Writers MACINTOSH o Richard Vega [GELAMP.MAC] MACINTOSH EDITOR """"""""" o Tom Trinko [T.TRINKO] Mac Staff Writer o Bret Fledderjohn [FLEDDERJOHN] Mac Staff Writer o Ricky J. Vega [GELAMP.MAC] Mac Staff Writer POWER PC o Ben Soulon [BEN.GELAMP] POWER PC EDITOR """""""" o Eric Shepherd [SHEPPY] Power PC Staff Writer WINDOWS o Bruce Maples [GELAMP.WIN] EDITOR """"""" o Tika Carr [LAMP.MM] Windows Staff Writer ETC. o Jim Lubin [J.LUBIN] Add Aladdin Scripts """" o Scott Garrigus [S.GARRIGUS] Search-ME! o Mike White [MWHITE] (oo) / DigiPub SysOp o John Peters [GENIELAMP] DigiPub SysOp o Phil Shapiro [P.SHAPIRO1] Contributing Columnist o Sanford E. Wolf [S.WOLF4] Contributing Columnist o Douglas Parks [DELUXE] Contributing Columnist \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\//////////////////////////////////// Opinions expressed herein are those of the individual authors, and do not necessarily represent opinions of GEnie Information Services, GEnieLamp Online Magazines, or T/TalkNet Online Publishing. Bulletin board messages are reprinted verbatim, and are included in this publi- cation with permission from GEnie Information Services and the source RoundTable. GEnie Information Services, GEnieLamp Online Magazines, and T/TalkNet Publishing do not guarantee the accuracy or suitability of any information included herein. We reserve the right to edit all letters and copy. Material published in this edition may be reprinted under the fol- lowing terms only. Reprint permission granted, unless otherwise noted, to registered computer user groups and not for profit publications. All articles must remain unedited and include the issue number and author at the top of each article reprinted. Please include the fol- lowing at the end of all reprints: \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/////////////////////////////////// The preceeding article is reprinted courtesy of GEnieLamp Online Magazine. (c) Copyright 1995 T/TalkNET Publishing and GEnie Infor- mation Services. Join GEnie now and receive $50.00 worth of online credit. To join GEnie, set your modem to 9600 baud (or less) and half duplex (local echo). Have the modem dial 1-800-638-8369 in the United States or 1-800-387-8330 in Canada. When you see the U#= prompt, type: JOINGENIE and hit the RETURN key. When you get the prompt asking for the signup code, type DSD524 and hit RETURN. GEnie will then ask you for your signup information. For more information call (voice) 1-800-638-9636. ////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ [EOF]