This package has been released to the public domain, for the sole purpose to be used by individuals to create and share with others their work that this package makes possible. The author still retains all copyrights to the material contained herein and as such this package may not be distributed by any means for profit. It may be freely passed around in it's original electronic form, either arc'd or unarc'd, with it's entire contents intact, with no parts of it modified or removed, including this message. The only charge that may be applied is the actual cost for distribution, unless the distribution is by a recognized Commodore User Group, where the only charge may be the group's normal library disk fee.
geoSHELL is the Copyrighted work of Maurice Randall
GEOS is a product of Berkeley Softworks (Geoworks) and Creative Micro Designs
Commodore 64 and 128 are products of Commodore Business Machines
CMD HD, FD, and RamLink are products of Creative Micro Designs
@TABLE OF CONTENTS
AN INTRODUCT
@TABLE OF CONTENTS
AN INTRODUCTION TO THIS MANUAL 1-2
A QUICK TUTORIAL 1-5
THE geoSHELL STYLE 1-7
USE geoSHELL TO YOUR ADVANTAGE 1-10
GETTING PARAMETERS FROM THE USER 1-11
THE DIFFERENT COMMAND MODES 1-12
EXITING YOUR COMMAND 1-13
WORKING WITH FILENAMES AND DRIVES 1-15
WORKING WITH PRINTERS 1-17
DISPLAYING MESSAGES 1-18
DISPLAYING LARGE AMOUNTS OF TEXT 1-20
COLORING THE 80 COLUMN SCREEN 1-22
THE ACCESSIBLE ROUTINES / With Examples 2-1
THE APPENDIX
A. Memory Usage A-1
B. Messages And Constants B-1
C. Modes And Their Values C-1
D. The Included Source Code D-1
INDEX I-1
Routines Indexed By Topic I-1
Disk Or Drive Related I-1
Keyboard Related Routines I-2
Input Related Routines I-2
Printer Routines I-2
Screen And Window Routines I-2
Text Displaying I-3
Text And Number Conversions Routines I-4
Error Related Routines I-4
Command Related I-5
Memory Related Routines I-5
Alphabetical Index To Routines I-6
Index To Variables
And Other Memory Locations I-8
Miscellaneous Index I-9
UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
@AN INTRODUCTION TO THIS MANUAL
This manual is a part of a new development package for developing commands to be used with geoSHELL, the command line interface for GEOS.
This manual isn't going to explain much about geoSHELL from the user's point of view, the geoSHELL User's Manual does that. And I would assume that if you are planning on writing commands for geoSHELL, that you more than likely are already somewhat familiar with the basic operation of geoSHELL.
In order to create a new command for geoSHELL, you should be familiar with machine language programming in GEOS and likewise will need the GEOPROGRAMMER package that was developed by Berkeley Softworks (now known as GEOWORKS) and is now available from CMD Sales, a division of Creative Micro Designs. All of the source code included here and all of the references to macros and variables is compatible only with GeoProgrammer and as such is in GeoWrite format. From this point on, it will be assumed that you do indeed have the GEOPROGRAMMER package and are familiar with using it to write programs for GEOS.
I put a great deal of effort into making geoSHELL easy to use and understand and I hope that throughout this manual and accompanying files, that I have achieved the same results by making it easy for you to become familiar with the inner workings of geoSHELL, and have supplied enough material, so that you might be able to use the information contained here to write new commands for yourself and others to use and enjoy.
Throughout this manual, there are programming examples, and when this document is printed on your printer, some of the characters may not print as they will appear in GeoWrite, depending on how your printer is configured. Since you will be printing this document using your printer's own built-in fonts, here is a list of the characters that are most likely to look different than what they really are:
^ The UP-ARROW
| The CMDR/UP-ARROW
{ A LEFT CURLY-BRACE
} A RIGHT CURLY-BRACE
# The POUND sign
[ A LEFT BRACKET
] A RIGHT BRACKET
_ An UNDERLINE character
< A LESS-THAN character
> A GREATER-THAN character
If none of these characters appear as described, you will have to remember this as you read through the document, or check your printer manual and make the needed changes to your printer. If they look correct, then you are all set. The only other way out is to painstakingly print this document using GeoWrite's 'HIGH' print setting, which uses the graphic mode of your printer. There are a lot of pages, this will take a great deal of time.
While reading through this manual, think about the
terminology that is used. Some of my methods may not be the same as yours or anybody else
terminology that is used. Some of my methods may not be the same as yours or anybody else's for that matter, but I think that I have put it in words that might be fairly easy to follow and understand. There are references to the current drive or currently active drive here and there. Usually, the currently active drive is the one that the user thinks is the current drive, the one represented by the drive letter that is displayed at the left of the command line. A reference to the current drive might be the one that is currently being accessed, however. Hopefully you will make this distinction. The variable PRESDRIVE always contains the device number of the currently active drive that the users sees. Whereas, the current drive would be contained in curDrive.
I have put this development package into the public domain and it may be freely distributed by anyone as long as it is not sold for any amount of money for profit. The only fee that may be charged for it's distribution would be enough to cover the cost of copying and mailing. This allows registered Commodore user groups to put the package into their library and charge their members the normal library disk fee to obtain it. Any individual may privately give out copies of this package as long as there is no charge to do so. Any other person or group or organization must obtain written permission from myself, the holder of the copyright, before being allowed to distribute it in any form. It is also assumed that anyone using this package is also an owner of an original geoSHELL disk and manual and is registered as such. For those who aren't, it is assumed that you are not using this package as an aid in creating commands for geoSHELL, but possibly as an aid in creating program's of other types for GEOS in general. Please feel free to use the information contained here if it helps to keep the GEOS format alive. But you will find that in most part, this package pertains mainly to geoSHELL.
With that out of the way, let's get down to business. Read through this documentation and study some of the sample source code that is included. Look through the section of this manual that covers each of the accessible routines in geoSHELL and try to imagine what you might be able to do with some of those routines. Think of a useful command that you wish geoSHELL had, and then create that command. If you come up with something useful, upload it to some of the major networks and share it with other geoSHELL owners or send it to me so that I can include it with other commands that I will create for geoSHELL owners to use. Anything that you create with this package should be kept as public domain. The only commercial part of geoSHELL is the main program and it's accompanying manual.
I hope this package is helpful, and please write to me with any problems or further questions that this package does not answer for you. If you create something useful, let me know.
Maurice Randall
P.O. Box 606
Charlotte MI 48813
PH: (517) 543-5202 (daytime phone and answering machine)
Using a P.O. Box, I will always be able to receive your mail, since my residence address could possibly change. If you are ever in the Charlotte, Michigan area though, stop in and say hi
Using a P.O. Box, I will always be able to receive your mail, since my residence address could possibly change. If you are ever in the Charlotte, Michigan area though, stop in and say hi at my shop during the daytime hours at:
Automotive Performance
426 Sumpter St.
Charlotte MI 48813
There is no shareware fee involved with using this package. You may use it free of charge. Being a registered owner of geoSHELL entitles you to use this package. Just write to me and let me know that you are using it so that if I discover any errors or create any updates, I can keep you informed as such. By the same token, please let me know if you find any errors anywhere. I've done considerable proofreading of this entire document and rechecked it with the original source code for geoSHELL. But, I'm just human also. I think, though, that you will find this to be quite error-free and I hope that you can make good use of it.
@A QUICK TUTORIAL
@A QUICK TUTORIAL
Included with this package are three files that are the very most basic templates that you can have when you start to create a geoSHELL command. They are appropriately named Sample, SampleHdr, and Sample.lnk. Copy these three files along with GSVariables.rel to either a separate work disk or your ram disk. Don't use the original files, use copies. You are about to create your very first geoSHELL command. Be sure that you also have GEOASSEMBLER and GEOLINKER on your disk. You can split these files between drives A and B if you'd like. The other files you will need were included with your GEOPROGRAMMER package. They are geosSym and geosMac. Copy these to drive A or B also. And don't forget GEOWRITE, since that is the text editor that we use.
Start by loading 'Sample' into GeoWrite and study the contents of this file. In it you will see where you would add the code that makes up your command. The very first instruction that will be in this file, where the label 'Sample' is found is where geoSHELL will jump to when it executes your command. From this point on, until you reach the instruction 'jmp ExitCommand', your command will be in control of the machine.
You can have your command do most anything you can think of, within reason, and within the limitations of your machine and the limitations imposed by the memory given to you. We won't worry about any of this for now, because this first command will be very small and will work just fine, hopefully on the first try.
Where the label, 'Sample' is, type in the following code exactly like you see it here:
Sample:
LoadW r0,#nameText ;point r0 at some text.
lda #(IN_ONE|TR_CR) ;formatting info.
jsr OtherMessage ;display a message.
jmp ExitCommand ;quit the command.
nameText:
.byte "John Doe",0 ;use your name instead.
Now load up GEOASSEMBLER. If you're using geoSHELL, just type the hotkeys, 'as', to run it. Assemble the file SampleHdr and then assemble Sample. If everything was done properly, these two files should have assembled without any errors.
Exit out of GEOASSEMBLER and load up GEOLINKER. With geoSHELL, type the hotkeys, 'li', to run it. Now, from GEOLINKER's menu, select the file 'Sample.lnk' and proceed to finish creating your first command. Once again, if everything was done properly, GEOLINKER will finish with no errors and you will have a file on your disk called 'sample'.
If you came up with any errors while assembling or linking, you will have to go back and check the files for errors. When you've corrected the problem, try assembling and linking again.
Now that you have a new command called 'sample', try it out. Just enter the command's name from geoSHELL and see what it does. If it works as expected, you will see your name displayed within
the geoSHELL window.
What your command did was to access the built-in routine OtherMessage to display the text string that r0 w
the geoSHELL window.
What your command did was to access the built-in routine OtherMessage to display the text string that r0 was pointing at. Just before calling the routine, you loaded the accumulator with a value that told OtherMessage how you wanted the text displayed. In this case, we or'd #IN_ONE with #TR_CR. IN_ONE tells OtherMessage to indent one character, and TR_CR tells it to add a trailing carriage return after displaying the message.
When you are ready to go further, take these same sample files and rename them appropriately to reflect the command you are creating. Be sure to go into the SampleHdr file and change the areas that should be altered, such as your name should go where the author's name is. You can also add a message in the Hdr file that will show up in the Desktop's info box or with geoSHELL's info command. Load the .lnk file into GeoWrite and change the names of the files contained in it. Always leave the file GSVariables.rel as the first file to link and you will have access to all of the variables that are accessible in geoSHELL. GSVariables does not add anything to the size of your code, it only gives access to the variables and equates.
Read through this manual and check out all of the features of geoSHELL that are available to you and then think of some ideas for some new commands.
@THE geoSHELL STYLE
When you create your commands for geoSHELL, try to stick to the style that e
@THE geoSHELL STYLE
When you create your commands for geoSHELL, try to stick to the style that everyone is accustomed to. A command's name should be all lower-case letters. It's easier to type when you don't have to hold down the shift key. Keep any required parameters simple and easy to remember. If your command requires a destination of some sort, such as a disk drive or printer, make the requirement one letter, if possible, followed by a space and then a filename if it is required.
You are actually free to do what you want, but people get used to doing things a certain way. Keep that in mind. It is hard for some people to get the hang of using geoSHELL after becoming familiar with the Desktop. But once they have used geoSHELL for awhile, they find out just how easy and powerful it really is. Keep this in mind if you try to change the style that geoSHELL users are now familiar with.
geoSHELL comes with a fairly complete online help file and a help command for accessing it. But since new commands are not included in the help file, it would be a good idea to display a short bit of information on the screen when the user enters the wrong parameter after your command. If no parameters are required, then there would be no need for this. Your command would just do it's thing and exit. You would still want to have error messages displayed when your command detects an error, however. This manual will explain how to display messages on the geoSHELL window. There are also examples in the sample source code that you can cut and paste into your own source code. That will make it easier to get it right the first time.
Your command, if you decide to share it with others should also include complete documentation. Don't make everyone try to figure out how to use it or exactly what it does. Explain everything, and in a manner that everyone can understand. Even the most expert of people prefer simple instructions. Put your documentation in GeoWrite format. If you create it with a 64, the 128 can still read it on the screen, since a 128 will display the full page width. But if you create the documentation on a 128, think of the 64 users also. Remember that they can only display half of the page width. So, it is acceptable to format the documentation with the right-hand margin set at 4.1 inches. Set the left margin all the way to the left. 64 users should select a 'full page wide' from the menus in order to get the left margin set at .2 inch, thereby making the document a V2.1 file. If a 128 user loads a V2.0 file into GeoWrite, the first thing he is asked is if he wishes to convert it to 2.1. This can be alarming sometimes or annoying if reading the original doc file on a write-protected disk. By keeping the right margin at 4.1 inches, a 64 user won't have to scroll to the right as he is reading the text. If the user wishes to print out the documentation, he is free to reformat the text to any margin settings he desires, but for just reading on the screen, it is very disturbing to have to scroll back and forth.
Once you have a full working command with absolutely no bugs and wish to share it with others, use one of the convert programs (2.5 compatible) or the new convert command for geoSHELL to
convert the command and the documentation to Commodore format and then use one of the arc utilities to arc the files together. This way the command and it's docs stay together when uploading and downloading. Anyone that does any amount of downloading from a BBS or major network should have the utilities to unarc a file. Of course, an easier way is to create a self-dissolving arc file. Then the user merely has to load and run the file to dissolve and then use convert to get the files back into GEOS format.
Always think of the person that is going to use your command. Keep in mind also the many different combinations of hardware that is possible with GEOS. There are many different drive setups that can be used and many different printers. Try to be compatible with everybody. If you are creating a command for yourself, then just do what only you need. But if you are going to share with someone else, keep this in mind. If you stick with the proven routines in geoSHELL, then your command should be compatible with any of the drives that are available.
Also, try to decide if your command will work with both the 64 and 128. If it is specific to the 128's 80 column mode, be sure to check the system that is being used. If you put the correct identification byte in the command's header block, then geoSHELL will do the checking for you before your command is loaded. But there is one catch to this. When a command is used once, it will stay in memory until another transient command overwrites it. If the machine is a 128 and your command only works in 80 column mode, for instance, geoSHELL will, of course, allow the command to execute if the user is currently in 80 column mode. But, once the command is in memory, it is possible that the user could switch to 40 columns and enter the command again. And if your command does nasty stuff in 40 column mode or vice-versa, that wouldn't be good. So, it is a good idea to test the screen mode before continuing with your command in these cases.
geoSHELL provides a variable to check that will tell you exactly the machine and the mode it is running in. The variable 'screenmode' is used for this. If bit 6 is set, the machine is a 64. If bit 7 is set, it is a 128 in 80 column mode. If screenmode equals 0, then the machine is a 128 in 40 column mode. In addition to this, the variable 'videomode' will tell you if the 128's 80 column screen is in multi-color mode or monochrome mode, in case your command needs to know. If bit 7 of videomode is set, the 128's 80 column screen is using color. This can be tested even while in 40 column mode, but is not effective unless the user switches to 80 columns.
Most commands will not have any reason to erase the geoSHELL window from the screen. It is a good idea to try and keep the window active, if at all possible. When your command exits, the user needs the window to be there in order to continue with something else. Of course, geoSHELL has routines that you can call to restore the window and whatever was in it. But when you erase it and do something different, there will be some routines that you won't want to access. The reason is that some geoSHELL routines will cause your command to cease if certain errors are encountered. If that happens and the window is not there, then the user just gets a blinking cursor without the window. He will
still be able to type in a command, but the effect might scare him. There are only two commands that are supplied with geoSHELL that ope
still be able to type in a command, but the effect might scare him. There are only two commands that are supplied with geoSHELL that operate without the geoSHELL window. One is 'dcopy' when
used with a 40 column screen, and the other is 'color80' with the 80 column screen of the 128. dcopy uses the computer's screen memory area for a buffer when transferring data from one disk to another. While it is doing this, it will blank all but the lower
portion of the screen where it displays, 'Please Wait - Disk Copy In Progress'. It still lets the user know what is going on. If it didn't display this, the user might think that the computer has locked up. As soon as the copying is finished, the screen is restored and the window looks just as it did before the copying began. Some of the sample source code contains the same routines that dcopy uses so that you can do the same thing in your code if you need some extra room while your command is running. If you have a 128, you've no doubt seen the color80 command and obviously this command doesn't need to have the geoSHELL window running. The color80 command shows that even graphic type commands may be used with geoSHELL. The source code for color80 is included in this package so that you can have an idea of how to do something similar.
The only thing to keep in mind is to make sure that your command can get the screen back into shape without using any of the geoSHELL routines that will stop your command. There aren't very many that will do this, but be aware of the ones that do. The description of each routine will tell you if this can happen. The routine that geoSHELL jumps through to halt your command is called 'NoMoreCmds'. This not only stops your command, but any others that the user might have typed in following yours will be ignored also. You can also jump through NoMoreCmds to halt your command in case of an error that you feel should return control to the user. Keep this in mind. In some cases, the user might type in two commands that relate to each other. If the first command detects a problem, it might not be a good idea to allow the second command to execute. This is something that you have to control in your command. Decide how serious of an error it is and then take appropriate action. You should try to display an error message and then jump to NoMoreCmds if the error is serious enough. If it is not something that would cause a problem, then just end your command the clean way with a jump through 'ExitCommand'. This routine will return control to geoSHELL in the same state as it was when your command first started. geoSHELL will then process further commands if there are any.
@USE geoSHELL TO YOUR ADVANTAGE
@USE geoSHELL TO YOUR ADVANTAGE
geoSHELL contains 101 routines that can be accessed from it's jump table. Use these routines to your advantage. Also, use the GEOS kernal routines. You can make your commands short if you can make use of what is already available to you. Some of geoSHELL's routines might never be useful to you, and some of them will be used in each and every command that you create.
Most simple commands can be written in just one or two pages of source code. The smaller they are, the faster they will load from disk. This is important to the user. Obviously, many commands that have already been written for geoSHELL could be translated into an application. One disadvantage to this would be that each application would end up being much larger and take up more room on a disk. Another disadvantage to this is that when the application is finished, geoSHELL or the Desktop must be reloaded from disk. geoSHELL commands do not remove geoSHELL from memory. It stays there. In fact, your command will also stay in memory until the user loads in another transient command from disk. This allows the user to do other things with geoSHELL and still be able to use your command again.
Another advantage to doing functions in GEOS with geoSHELL commands will be evident with those that use CMD devices. geoSHELL and all of it's commands can be placed in just one partition instead of having to have a copy in each partition like you would need if using the Desktop. Then, as long as the user identifies that partition with the 'path' command, geoSHELL will always have access to any of those commands, no matter which device or partition the user is working from. It is sort of like a big extention of the computer's memory. If your command were to perform some sort of printing function, the user merely types in the command and any required parameters, if needed, and the command is executed. The user doesn't even realize that geoSHELL changed partitions to get access to the command.
When geoSHELL executes your command, it turns control over to your command. Your command can now do what it is designed to do and then exit. The most simplest of commands would act as though they were just another routine in geoSHELL that is being jsr'd to. But you do not want to end your command with an 'rts'. This will not return you to geoSHELL's main processor. This returns you to the GEOS Kernal's mainloop. The reason geoSHELL was written to operate this way, was so that your command could make use of custom input routines and use the GEOS mainloop to catch user input. The command 'color80' works this way. At one point it will do an rts and wait for the user to click on an icon. It sets up an icon table for GEOS to look at when the user clicks the mouse. If you still want user input, and need a blinking cursor, geoSHELL has routines that will turn on the cursor for you, or turn it off, also. You will have to process the characters that the user enters. There are some routines that will do a certain amount of this for you. Plus, the GEOS kernal has routines for this also.
@GETTING PARAMETERS FROM THE USER
When the user types in
@GETTING PARAMETERS FROM THE USER
When the user types in your command and enters a required parameter, you will have access to that parameter in several ways. There is a table that geoSHELL creates at 'ParamTable'. This table is 43 bytes long. The 43rd byte will always be a null. If there is any data following your command, it will be placed in this table. If no parameter was entered, this table will be all zeros. If one or more parameters were entered, they will be placed here at least up to the point where geoSHELL either finds a carriage return or a terminator, which could be an up-arrow character or a null byte. The remainder of the bytes in the table will be nulls.
There is also a pointer into the actual buffer where the commands are coming from. The command pointer, a4, points to this buffer. This buffer can be in one of two places. If the commands are coming from the user at the keyboard, a4 will be pointing somewhere within the command buffer. If the commands are being executed from a startup file or an exec file, then a4 will be pointing somewhere within the startup buffer. geoSHELL looks where a4 is pointing when it is ready to execute the next command.
When you use ParamName to get the filename, a2 and r6 will both be pointing at it. They will also be null-terminated. As you know, the user is allowed to use wildcards when entering a filename. ParamName will identify this fact for you. If a wildcard (? or *) is used, bit 7 of WILDCARD will be set. If your command works like the 'rename' command where the user needs to type in two filenames with an equals (=) sign separating them, then ParamName will have bit 5 set if the equals sign was used properly. And in this case, a4, the command pointer, will automatically be updated to point at the second filename as well as a2, while r0 will be pointing at the first filename. Both will be null-terminated. If bit 7 is set in this case, it will still reflect wildcards in the filename that a2 is pointing at. You are not notified if wildcards exist in the filename that r0 is pointing at. In the case of the rename command, the first filename should be entered without wildcards anyway.
Even though ParamName points a2 at a filename and terminates it with a null byte, the bytes contained in ParamTable will not be affected. You can still get access to the exact characters that the user typed in.
If you need to use the filename that r0 points at in the case of the user entering two filenames, you might want to save the value contained in r0, since that is a fairly popular zero page location. a2 will not get changed unless you call a geoSHELL routine that purposely changes it.
Another variable that might be useful is 'paramsize'. When geoSHELL loads your command and fills ParamTable, it also sets the variable paramsize with the number of bytes that were copied to ParamTable.
@THE DIFFERENT COMMAND MODES
@THE DIFFERENT COMMAND MODES
If your command needs more than what can be typed in at the keyboard, it would have to be a command that would only execute from a 'startup' or 'exec' file. The user can enter as much as will fit in the exec file at least until it gets too large for the startup buffer. The startup buffer, which is also used for exec files, is 1536 bytes in size. This can accomodate all but the larger GeoWrite pages. When you need to access a parameter that is larger than ParamTable will hold, just read the parameters beginning with the byte that a4 is pointing at.
There is a way to tell if your command is being executed from the command line or a startup/exec file. The variable 'STUPMODE' will identify this for you. If bit 7 of STUPMODE is set, then the command is being executed from a startup or exec file. If bit 7 is cleared, the user typed in the command from the keyboard. If the command came from a function key press, then the variable 'FKEYMODE' will have it's bit 7 set, otherwise it will be cleared. So, in some cases, your command may or may not be compatible with these different modes. As an example, geoSHELL's 'echo' command is not allowed to run from the keyboard. There is no reason for it, even though it would do no harm.
When you are creating your command, test it to be sure that it will operate in these different modes. Try to make it compatible with any of the different ways that the user might want to use it. In most cases, you won't have any problem with your command in any of the different modes, unless it does something out of the ordinary.
@EXITING YOUR COMMAND
@EXITING YOUR COMMAND
The proper way to exit a command is through the routine 'ExitCommand'. This way, geoSHELL knows you are finished and it will then proceed to check if any more commands exist that need to be executed. If not, then it will return control to the user. If you simply did an 'rts' instead of 'jmp ExitCommand', you would return to the GEOS mainloop and the user would be stuck, unless your command itself was looking for user input through mainloop. If not, then the only way the user might get out of this situation would be to click on geoSHELL's close icon, and return to the Desktop. So, when testing your command, should you forget this, just click on the close icon, return to the Desktop and then you can get back into geoSHELL from there. If the Desktop isn't found by geoSHELL, then geoSHELL will grab control of the computer and give control back to the user. Just be sure to end your command with the jump through ExitCommand and the user won't run into this problem.
If you had any parameters that your command used, you are required to update the command pointer before you exit your command. Otherwise, geoSHELL will try to execute your parameter and that obviously would not work. If your parameter were a filename, geoSHELL would attempt to load and run that file. This may not be what you had intended, but you are in charge until your command exits, so do as you please. You can put the command pointer wherever you want, but in most cases, you would place it just past your parameter, so that geoSHELL can check for another command following it and do as the user expects.
There is a routine that helps you to adjust the command pointer. It is called 'IncCmdPointer'. If you did not use any parameters, then you would not need to worry about updating the pointer, because it would already be pointing at the next command. But if you had a parameter, you need to put the pointer past it and point at the next command if there is any. Remember that from the user's standpoint, you are required to put at least one space after a command's parameter, so the command pointer needs to be incremented by the number of bytes that make up the parameter plus one for the space that follows it. Assuming your command had a one-byte parameter, the following code would increment the command pointer properly:
lda #2
jsr IncCmdPointer
You must load the accumulator with the amount to increment and then call the routine. If your parameter was a filename, and it contained 10 characters, you would have to increment the pointer by 11. geoSHELL will count the length of your filename for you if you use the routine 'ParamName' to fetch the filename that the user typed in. The length of the filename will be contained in 'NUM_IN_NAME'. Just load the accumulator with the value in NUM_IN_NAME and add 1 to it for at least one trailing space, and then call IncCmdPointer. Refer to the information about these routines for more sample source code on how to use them properly.
ith the byte that a4 is pointing at.
There is a way to tell if your command is being executed from the command line or a startu
If you were grabbing parameters directly from the command buffer or startup buffer if the command was executed from a startup or exec file (a4 points to the first parameter either way), then you might just manually update the command pointer (a4) as you go. The following code would do this:
ldy #0
lda (a4),y
... ;do what you need with the byte.
... ;somewhere in here you might
... ;branch out to 20$ if done.
iny ;or branch to here.
bne 10$
inc a4H ;keep a4 pointing properly.
bne 10$ ;branch always.
iny ;one past our parameter.
bne 30$
inc a4H ;in case y incremented to zero.
tya ;increment the last little bit.
jsr IncCmdPointer
... ;continue on
@WORKING WITH FILENAMES AND DRIVES
You've learned how to get a2 to point to the filename that the user has typed in. Now let's see how we can find a filename on a disk. There are several routines for doing this. You no doubt know of some of the routines that are built into the GEOS kernal for finding a file or accessing a file in some manner. But if you merely take the filename that a2 is pointing at and do the following routine, it might not work.
MoveW a2,r6 ;point r6 to filename
jsr FindFile ;and use GEOS kernal
;to find it.
You are probably wondering why this wouldn't work. When using the DeskTop, the user clicks on an icon. The DeskTop knows the exact spelling of the file and the drive it is located on (the currently open drive). But with geoSHELL, the user can type in anything. What if the user included some wildcards in the filename? GEOS doesn't work with wildcards. Those have to be handled by the application. geoSHELL will do this for you. In fact, it is all handled automatically. And there are several routines you can call depending on the search you would like to perform. Here's one example:
jsr CkPresdrive ;find the file on the
;currently active drive.
bit goodflag ;Is it there?
bmi 50$ ;branch if so.
This example would search the currently active drive for the filename that the user typed in. This would be the drive that the user sees as being open, according to the letter that is displayed at the left of the line. You can tell which drive it is by checking the value of PRESDRIVE. This variable always holds the device number of the user's currently active drive, or the 'present' drive. Using geoSHELL routines to search for filenames will properly handle the wildcards for your command. If the file is found, the variable 'goodflag' will have it's bit 7 set and your command will be able to then process the file as needed. Another thing that these routines do for you is that now a2 is pointing at the actual name of the file as it exists on the disk. The wildcards are converted into the characters that they are supposed to represent. Now the standard GEOS routines can process the filename because you know the exact name as it appears on the disk. If you wanted to keep a copy of the filename that the user typed in, then you might want to save a copy of where a2 is pointing before calling the routine. The routine will actually point a2 at a different location, where geoSHELL assembled the correct filename for you. This location is usually at 'filetoload'. Most of the time, you won't have a need for the original name, just the correct one. If geoSHELL doesn't find the file, then a2 won't change.
geoSHELL has many ways to search for a file. Here are the different methods you can select from, depending on what you intend to accomplish:
geoSHELL has many ways to search for a file. Here are the different methods you can select from, depending on what you intend to accomplish:
CkPresdrive will search the current drive.
CkAllDrives will search all of the drives except the path partition, unless that particular partition is currently open on one of the drives.
CkThisDrive will search the drive that you specify in the accumulator. Just load the accumulator with a value from 8-11.
CkOtherDrives will search any drive that you haven't yet searched with CkThisDrive. This allows you to use CkThisDrive to pick and choose the exact order you want, and then use CkOtherDrives to search all remaining drives. The path partition is ignored.
CkPath will search the path partition.
CkPathOrder will search a specific order with certain priorities. First all ramdisks are searched, then the path partition, and finally any remaining drives.
FindParName will search the currently active drive just like CkPresdrive does, except you don't have to supply the filename for the search. This routine will get it for you, since it calls ParamName to get the filename. The only drawback to this routine is that if the file is not found, it will exit through NoMoreCmds and your command will end. Be sure that the geoSHELL window is active if you use this routine.
Each of these routines will deal with any wildcards if contained in the filename that a2 points at. You can always test goodflag for a successful search. If goodflag is set, indicating that the file was found, then the variable DRVFOUNDON will contain the device number where the file was found. Plus the drive that contains the file will be open so that you do not have to call SetDevice or OpenDisk.
If you called a routine that searches the path partition, and if the file is found on that partition, then 'pathload' will have it's bit 7 set. In this case, you will be left with the path partition open. It is your responsibility to restore the partition that was previously open once you are through with that file and before you exit your command. Otherwise, the user might not appreciate it. There is a simple routine in geoSHELL to do this for you. It is called ResetFromPath. Call this when you are finished with the file and are ready to close the partition. ResetFromPath will reopen the original partition on the path device and will also reselect the drive specified in PRESDRIVE. Also be sure to call ResetFromPath before using any routine that could cause your command to cease. You wouldn't want to leave the user in the wrong partition when control returns to him. You can always reopen the path partition if need be. It all works fairly quick, so it would not slow your command down to any noticable degree.
s. The path partition is ignored.
Ckl if your command is being executed from the command line or a startu
There are routines in geoSHELL for accessing a printer or interface connected to the serial port. Unfortunately, they were mistakenly left out of the jump table. The '@p' command causes geoSHELL to send output to the printer through these routines. In the sample source code files that are included with this package, you will find some source code that you can put in your command for accessing the serial printer or interface.
On a brighter note, the routines that access a printer connected to the user port with a geoCable 'is' in the jump table. There are two routines, Open_GC_Channel and Send_GC_Byte. You don't have to call Open_GC_Channel. However, it is a good idea to do so, because it will check to make sure there is a printer connected and responding before you attempt to send any bytes to it. This routine will return with x=0 if a printer was found and is able to accept data. The universal 'goodflag' is not used with this routine. Once you are sure that a printer is there, use Send_GC_Byte to transmit the bytes. Just load the accumulator with the byte to send and call the routine.
One of the things you might want to try when testing your routine is to see how it works with the @p or @g command, even if your command has nothing to do with the printer itself. Make sure that when geoSHELL is sending screen output to the printer, that your command will work with it. If not, then you would want to either inform the user with an error message, or turn the printer output off yourself. You can check this with the variable PRNTMODE. Any non-zero value here will send output to a printer. Bit 7 set goes to the serial port and bit 6 set goes to the user port. You can turn these off if the printer doesn't get along with your command for some reason. Just be sure to restore it before you exit your command.
@DISPLAYING MESSAGES
geoSHELL is full of messages. A g
@DISPLAYING MESSAGES
geoSHELL is full of messages. A good deal of the program is involved with sending messages to the screen in order to inform the user what is taking place. But it seems as though there were times when it should have even more messages.
As geoSHELL evolved, it grew larger and larger. At one point in time, it did not have the ability to use transient commands. All commands were contained in memory and so every command was considered a resident command. But it got to the point where something had to go. So, some commands were removed from geoSHELL and made into transient commands. Some were moved into VLIR records in the geoSHELL file and others were placed in their own separate files as external transients. This also allowed many of geoSHELL's messages to get moved out of memory and into the transient commands. In this way, more messages could be added to the commands themselves, since they would not require any of geoSHELL's main memory. But, I guess you just can't have enough messages. Not everybody will read a manual, but they will usually notice a message that is displayed in front of them.
So, you will want to keep the user informed of any error that occurs, or, if your command is doing something that might require some processing time, let the user know about it. Don't make him think that his computer has just locked up. But, keep your messages short and to the point. Another thing to remember is to keep your messages limited in length. Remember, a 128 user might be able to have an 80 character message on his screen, but a 64 user can't. So, for the longer messages, you will have to break them up into two lines. Remember that a 128 user might also be in 40 column mode. You have 40 columns to work with, so keep the messages to a maximum of 40 characters including any spaces.
There are two routines that will help you to display a message to the screen, 'Message' and 'OtherMessage'. The routine Message will allow you to have access to the messages that are built-in to geoSHELL. If you can use any of these, it will make your own command that much smaller. OtherMessage lets you use messages that are contained in your command. Here is a couple of examples:
;Example #1
ldx #15
lda #(IN_TWO|TR_CR)
jsr Message
;Example #2
LoadW r0,#wrongText
lda #(IN_TWO|TR_CR)
jsr OtherMessage
wrongText:
.byte "Wrong Filetype!",0
geoSHELL evolved, it grew larger and larger. At o
In the first example, you will be displaying the internal message #15 because you loaded x with 15 and called Message. Message #15 will display 'Insufficient Room On Disk!'. Notice that you also had to load the accumulator with a value. This value tells the message routine how to display your message. There are some constants for this. The ones we used here are IN_TWO and TR_CR. The first one, IN_TWO, stands for 'initial two spaces', and will make the message appear two spaces over from where the cursor is and the second one, TR_CR, stands for 'trailing carriage return', and will produce a carriage return after your message is displayed.
The second example above uses OtherMessage. Here, you have to point r0 to a null-terminated string, load the accumulator with the formatting information and then call the routine.
If a message causes printing to exceed the limit of the 40 column screen, it will simply be chopped off at the right side. No harm will occur, other than the user won't see the whole message.
In the Appendix, you will find a list of the built-in messages that you can access along with the different constants that can be loaded into the accumulator before calling these routines.
@DISPLAYING LARGE AMOUNTS OF TEXT
If you need to display large amounts of text, there are routines in geoSHELL for doing this, complete with word-wrap. The 'type' and 'echo' commands make use of these routines.
The echo command can display any text following it until it encounters either a null byte or an up-arrow terminator. Here is a method you can use that is similar to the one that the echo command uses:
LoadB endecho,#128 ;initialize a flag.
LoadB typeset,#0 ;ignore tabs and carriage
;returns.
MoveW a4,r0 ;point r0 to the start
;of your parameter or the text
;that follows your command.
jsr DispText ;display up to 80 columns
;of text.
jsr AdjTxtPointer ;advance a pointer to
;some more of the text.
bit endecho ;have we reached the end?
bmi 10$ ;branch if not.
MoveW r0,a4 ;adjust the command pointer.
In the above example, using DispText and AdjTxtPointer together, you can display any text that r0 points at. In this example, we are displaying text that follows our command since we are pointing r0 at the same spot that a4 is pointing at. DispText will give you word wrap, because it will only display complete words to the screen. Calling AdjTxtPointer will point r0 at the first word that DispText didn't display. We know that we have reached the end of the text when bit 7 of endecho is cleared. The routine starts out by setting endecho's bit 7, otherwise only one line of text will get displayed. Then as long as bit 7 remains set, there is still some text left and so we loop back to display some more. The above routine will terminate if a null byte or an up-arrow terminator is reached. It will work this way if typeset is set to zero. If bit 7 of typeset is set, then an up-arrow will not terminate the routine, only a null byte will. Also, this would cause carriage returns and tabs to be recognized. A tab will not be treated as a true tab, but will be expanded to equal 5 spaces. That is how the 'type' command works with DispText. Of course, though, since the type command is capable of displaying almost any kind of text file, it also does some other processing of the text it reads from disk before passing it on to DispText. DispText only understands true ascii text. DispText will also call routines that will scroll the text when it reaches the bottom of the geoSHELL window. CkKeyboard is also called to allow the user to pause or stop the text. If the STOP key is pressed, your command will terminate and control will return to the user. So you should only use these routines if the geoSHELL window is active. The routines are designed to display text in the window,
anyways.
anyways. If you wish to defeat this, you can turn the keyboard off by setting bit 7 in the variable 'kboardoff'. If you set bit 6, then only the STOP key will be ignored. Reset kboardoff to zero when you are finished.
@COLORING THE 80 COLUMN SCREEN
geoSHELL has a command called 'rgb' that allows a user of the 128 with a color monitor to display geoSHELL in multiple colors, instead of just the two colors that GEOS uses for most applications. Since geoSHELL has been given this ability, the routine to put the color on the screen has been made available in the jump table so that any command can have access to the same routine and add color if it operates outside of the geoSHELL window. This is what the command 'color80' does. The routine that puts color on the screen is called 'ColorScreen'.
Before attempting to color the screen, you should be sure that the user has put the computer in color mode. First, your command should check to make sure that the machine is a 128 in 80 column mode. Test bit 7 of screenmode to check for 80 column mode. If it is set, then the machine is a 128 running in 80 columns. Following this, test bit 7 of videomode. If it is set, then the user has selected color mode with the 'rgb' command. If this all checks out OK, then you can proceed with your command. If the machine is not a 128 in 80 column color mode, then you should inform the user as such, and then exit the command appropriately.
ColorScreen expects two things, a table of compressed bytes pointed at by r0, which from here on we will call a 'Color Scrap', and a table of color combinations pointed at by r1. In the table of color combinations, there can be as many as 255 different combinations of colors. The reason that a separate table is used for the colors is to make it easy to alter the colors in any Color Scrap just by modifying the different color combinations in this table instead of having to go through the Scrap itself and changing each color byte. The colors can be changed very easily while your command is running, or while you are developing the source code. Each combination is a one byte value consisting of a foreground color and a background color. The foreground color (0-15) is stored in the upper nybble of the byte, while the background color is stored in the lower nybble. So, a byte that defines a black foreground with a white background would be (BLACK80<<4)|WHITE80. Using GeoAssembler, this will shift the value of BLACK80 left 4 bits and 'or' it with WHITE80. In hexidecimal form it would be $0f, since BLACK80 equals 0 and WHITE80 equals 15. In the description for the Color Scrap, you will see how ColorScreen uses this table of color combinations. Here are all of the equates that you can use instead of having to remember which color number corresponds to which color. These equates are all assembled in GSVariables.rel.
BLACK80 = 0 ;black
DK80GREY = 1 ;dark grey
DK80BLUE = 2 ;dark blue
LT80BLUE = 3 ;light blue
DK80GREEN = 4 ;dark green
LT80GREEN = 5 ;light green
DK80CYAN = 6 ;dark cyan
LT80CYAN = 7 ;light cyan
DK80RED = 8 ;dark red
LT80RED = 9 ;light red
DK80PURPLE = 10 ;dark purple
LT80PURPLE
LT80RED = 9 ;light red
DK80PURPLE = 10 ;dark purple
LT80PURPLE = 11 ;light purple
DK80YELLOW = 12 ;dark yellow
LT80YELLOW = 13 ;light yellow
LT80GREY = 14 ;light grey
WHITE80 = 15 ;white
The Color Scrap defines the areas of the screen that you would like to have color applied or changed from what is currently there. You can color anything from one 8 x 8 pixel area to the full screen. The screen is made up of 1760 individual areas that we can add color to. Normally, there is 2000 areas, but since geoSHELL doesn't use the lower 3 rows when in rgb mode, we are limited to 1760 color areas. These areas correspond to the same character locations if the screen were in text mode such as when you first turn the computer on. We will refer to each area as a card. There are 22 lines of 80 cards on the screen that we can add color to. Each card or line is eight pixels high and each card is eight pixels wide. In the VDC chip's own memory, there are 1760 bytes that hold the color information for each card on the screen. The first byte corresponds to the card at the upper left corner of the screen. Bytes 0-79 represent the cards in the first row. Bytes 80-159 represent the cards in the second row, and so on. So, you can see that each row is stored sequentially in memory. When designing a Color Scrap, you have to keep this arrangement in mind.
The lower three card rows that are blanked out are always in the same color as the border. This way, the blanked out rows just make the lower border area look thicker. geoSHELL provides you with a routine to change the border color. It is called SetBrdrColor. To use it you must first load brdrcolor with the desired color 0-15. Here again, make sure that the machine is in color mode.
Let's design a simple Color Scrap.
Here is how a Color Scrap is laid out:
byte 1 row (0-21) to begin at.
byte 2 column (0-79) to begin at.
byte 3 number of times (1-255) to repeat the next command.
byte 4 number of 2 byte commands (1-255) that follow.
byte 5 number of sequential cards (1-255) to color.
byte 6 offset (0-254) into color table of color to use.
If 255, then no coloring will take place, the routine will simply increment the number of cards defined by byte 5.
Bytes 5 and 6 are a pair of bytes that is the first command set in the number of command sets that is defined by byte 4. If byte 4 was a 2, then byte 7 and 8 will also be a command set. If byte 3 is a 2, then the group of bytes from byte 4 through byte 8 will be performed twice. In this case, then byte 9 will be the
start of the next group.
byte 9 If 0, then end of table.
If 255, then the next two bytes define a new row and
start of the next group.
byte 9 If 0, then end of table.
If 255, then the next two bytes define a new row and column to begin coloring from.
and so on until end of table...
;This example will color a 4 x 4 card box where the upper left ;corner of the box is at row 2, column 10.
ColorBox:
LoadW r0,#boxScrap
LoadW r1,#boxColors
jmp ColorScreen
boxScrap:
.byte 2,10 ;start at row 2, column 10.
.byte 4 ;repeat the next number of
;sets 4 times so that 4
;rows get colored.
.byte 2 ;number of command sets.
.byte 4,0 ;color 4 cards with
;color 0 (1st color combo)
;from the color table.
.byte 76,255 ;skip 76 cards without
;coloring.
.byte 0 ;end of table.
boxColors:
.byte (DK80RED<<4)|LT80GREY ;use one color combo
;with this example.
;this same color scrap could also be written like this to
;accomplish the same result.
boxScrap:
.byte 2,10 ;start at row 2, column 10.
.byte 1 ;repeat once.
.byte 1 ;number of command sets.
.byte 4,0 ;color 4 cards with color 0
;from the color table.
.byte 255 ;get a new starting value.
.byte 3,10 ;start at row 3, column 10.
.byte 1
.byte 1
.byte 4,0
.byte 255 ;get a new starting value.
.byte 4,10 ;start at row 4, column 10.
.byte 1
.byte 1
.byte 4,0
.byte 255 ;get a new starting value.
.byte 5,10 ;start at row 5, column 10.
.byte 1
.byte 1
.byte 4,0
.byte 0 ;end of tabl
.byte 1
.byte 4,0
.byte 0 ;end of table.
Even though this would accomplish the same result, it requires a bigger table and will also take about twice as long to put the color on the screen, although the difference in speed can't be seen with the eye. So, when you are creating your Color Scrap, think if you can make it more compact. Here is an example that will put color on the whole screen.
.byte 0,0 ;start at row 1, column 1.
.byte 22 ;repeat 22 times.
.byte 1 ;one command set.
.byte 80,0 ;color 80 cards with 1st
;color from table.
.byte 0 ;end of table.
Once you get the hang of it, you will find it rather easy to create quite complex Color Scraps. Putting color on the 80 column screen really adds to it's appeal. There is no reason not to do it with any new GEOS application, not just geoSHELL. The only drawback is that not everybody has 64K of video ram in their 128s. This is why geoSHELL limits the coloring of the screen to the first 22 card rows due so that the users with only 16K of video ram will still be able to have color.
When you are using the 80 column color screen, remember that when you use geoSHELL to clear the screen for you with ClearScreen, it will clear it with the background pattern that is stored in clr80pattern. Depending on what you are doing with the screen, the background pattern that the user has chosen for the geoSHELL screen may not look good with your command. The trick here is to store the pattern byte that you want at clr80pattern and restore the original one before your command exits. In fact, you can do that with any of the color or pattern bytes that geoSHELL stores beginning at coltable. Here is a list of those variables, and you can see that all of the pattern bytes are stored just after the color variables.
coltable: ;80 column color table.
backcolor: .block 1 ;screen background color.
shellcolor: .block 1 ;shell color.
textcolor: .block 1 ;text color.
padcolor: .block 1 ;pad background color.
brdrcolor: .block 1 ;screen border color.
back40pattern: .block 1 ;backgrnd pattern for 40 column.
back80pattern: .block 1 ;backgrnd pattern for 80 column.
clr80pattern: .block 1 ;backgrnd pattern for RGB mode.
Feel free to experiment with different settings if your command needs to, but don't forget to restore them. If you change any of these variables, you won't see the effect until you force geoSHELL to clear the screen or redraw the geoSHELL window. Otherwise you will have to do your own coloring with ColorScreen.
@-- NOTES --
@-- NOTES --
The geoSHELL Programmer's Development Package 1-PAGE
it with any new GEOS application, not just geoSHELL. The only drawback is that not everybody has 64K of video ram in
The geoSHELL Programmer's Development Package 1-PAGE