================================================================ HyperStudio XCMD Specifications ------------------------------- Version 1.0 written 4/28/89 Version 2.0 written 9/02/89 Version 3.0 written 12/1/89 --------------------------- Original by Eric Mueller Updated by Ken Kashmarek ------------------------ ================================================================ IMPORTANT NOTE: There is a good chance these specifications will expand with future releases of HyperStudio. There is no guarantee that your XCMDs will be downward compatible. An XCMD that works with HyperStudio V2.0 should work under later versions. Please keep this is mind when experimenting with XCMDs. ================================================================ This file will outline the special protocol used to write XCMDs for HyperStudio, and document the special entry point used to access several internal functions. There are relatively few parameters at this time. When the user selects "Trigger an XCMD" as one of the button's actions, they receive a dialog which asks them to enter the text string which will be sent to the XCMD. This string gets inserted into the button's definition in the stack, allowing different messages from each button. When the user then pushes the button, HyperStudio calls the routine which is in file HS.XCMD on the disk (same directory as HyperStudio itself). The following apply: 1. The filetype of HS.XCMD must be $BC. The current code does not check to see if the filetype is $BC (general purpose load module). However, to be compatible with future versions, the HS.XCMD filetype should $BC. 2. The A-reg contains the userid of the XCMD module when it is invoked. This value is necessary if your file needs to obtain memory from the memory manager. 3. Y/X regs now contain the lo/hi pointer to the parameter list. The parameter list is described later. 4. Program control is passed in native mode with 16 bit registers (A/X/Y). Control must be returned to HyperStudio in native mode with full 16 bit registers. 5. The D-reg points to the HyperStudio direct page. This direct page is owned by HyperStudio. Do not modify the contents. If you use any direct page locations, they must be saved and restored. These locations must be restored when calling the HyperStudio subroutine interface. If you are programming using the supplied high level language interface, this is handled for you. 6. The S-reg points to the HyperStudio stack. Do not change any location above the stack pointer. The stack holds the RTL address for return to HyperStudio. 7. The XCMD program must return to HyperStudio via an RTL instruction. Do not use the QUIT call. 8. HyperStudio is running in a desktop environment. Do not start or stop any tools, or otherwise change the desktop environment. 9. Use the GS/OS prefixes as is (do not change them). 10. The XCMD file must be memory restartable. When the XCMD file gets control, the direct page and stack still belong to HyperStudio. The assembly language versions of the exerciser uses only the first four bytes of the direct page. The high level language versions allocate their own stack and direct page (the library interface saves and restores the HyperStudio pointers for you). The format of the parameter list pointed to by Y/X is as follows: 0- 1 WORD - ButtonID the ID of the button just pressed 2- 3 WORD - CurrentCardID the ID of the card we are currently on 4- 7 LONG - ScriptHandle Handle to the script itself 8-11 LONG - ScriptLength Length of the script 12-15 LONG - TextPassedPtr pointer to the command line text from the button (a Pascal string) 16-19 LONG - HSAddress entry point for HyperStudio internal functions The last LONG value is important. If you push the right parameters on the stack and set the X-reg with one of the given values (see below), you can use the HyperStudio internal functions: Value in X Function accessed ---------- ----------------- #0001 MoveToFirst (card, that is) #0002 MoveToLast #0003 MoveToPrevious #0004 MoveToNext #0005 MoveToCardIDNum #0006 RedrawCard #0007 LaunchStack (not available in v3.0) #0008 FindText An additional parameter for the extended functions is the ID for the MoveToCardIDNum call. Push a word on the stack prior to the call containing the ID of the desired card. If this value is zero, or is over the value for the last card in the stack, unexpected things may happen. Also note that ID numbers for cards do not directly correspond to card positions - when creating a new card, the card is assigned a unique card ID number that is not duplicated in the stack. FindText expects two parameters: pointer to a search string (Pascal string) and a word with the search flags. The search flags are defined as follows: bits 15 to 3 reserved bit 2 TRUE (on) = search editable fields bit 1 TRUE (on) = search read only fields bit 0 TRUE (on) = case sensitive CurrentCardID in the parameter list is updated after each card move call. HS.XCMD is loaded from the current prefix (prefix 0) that is in effect when HyperStudio is launched. If HS.XCMD is not found in that prefix, it is not loaded. If it is found, it is loaded. If a stack is loaded from that prefix, it will be able to use the module. When a stack is loaded, the prefix is changed to the directory of the stack. Whenever a new stack is loaded, the existing copy of HS.XCMD is removed and reloaded from the directory of the new stack. If a directory from which a stack is loaded does not have an XCMD file, the stacks loaded from that directory cannot use XCMDs. What the XCMD program does is up to the coder and stack designer. ================================================================ The HyperStudio Sample Program Suite HyperStudio XCMD Exerciser 01 December 1989 ================================================================ This complete freeware package contains several sample program XCMD files for Hyperstudio. It also contains one sample HyperStudio stack. The sample XCMD file provides the same demonstration of the capabilities. Each different file is done in a different language. At this writing, this includes: - Merlin assembler - ORCA/M or APW assembler - ORCA/Pascal - TML/Pascal - ORCA/C APW/C was deliberately left out since the compile/link process is so slow and produces such large load files. APW/C is just not a fast enough tool for development purposes. All files are packaged in compressed format, put together by Shrinkit. You will need Shrinkit to expand the files for use. An attempt was made to keep each version of the program the same where possible. Of course, between assembly language and the higher level languages, this seldom works. So, beware of small changes necessary to suit different languages. The high level language versions use a library to interface between the code and HyperStudio internal functions. This makes your job easier since you don't have to worry about the details of direct page, stack, and register manipulation. However, you MUST use the library interface, or your program will not work with HyperStudio. There are several differences between the Pascal versions. The C version has a few additional differences from the Pascal versions. You won't find any Basic programs in the sample program suite. None of the existing Basic compilers are suitable for producing an XCMD file. In some cases, high level language features were not always used, so the programs could be easily compared to one another. Debugging XCMD files is very difficult. Your program is running under HyperStudio, which does not supply programming interface support for testing and debugging. If you run into problems, double check the documentation, the sample programs, and your code. Then double check again. As your program development progresses, make only small changes so it is easier to isolate any problems that come up. While developing the sample program suite, I had a running program to work with. Therefore, it was easy to see what the result should be. One significant note for all languages: The file, HS.XCMD, is loaded when a HyperStudio stack is loaded from a directory. It is kept in memory while the stack is in memory. The program must be reusable from memory (memory restartable). HS.XCMD must initialize itself correctly the first time it is called, and all memory contents must be valid for each subsequent call. The sample program and interface do not support the Launch Stack option. This option will be removed, changed, or otherwise be different at some point in the future. While HyperStudio will read the data fork from extended files, it does not yet support the resource fork. That is, the Resource Manager is not started. Do not start or attempt to use the Resource Manager at this time. It may conflict with a future version of HyperStudio. A word of caution to APW and ORCA/M users: Apple Computer, Inc., has supplied new utilities for APW to assist in developing applications under GS/OS V3, which is on System Disk V5.02. Some of these utilities deal with creation and manipulation of OMF2 files. These new utilities were NOT used for this effort. There are some compatibility issues between the old OMF1 utilities and the new OMF2 utilities. XCMDLIB is delivered in OMF1 format. It may not be usable with the new OMF2 utilities. If you run into problems with the new OMF2 utilities, report them to Apple Computer, Inc. ================================================================ Merlin Assembler The original version of the XCMD exerciser was written by Eric C. Mueller, using Merlin 16+. The existing version in this package has been significantly modified to make it easier to understand the mechanics of using the assembler language subroutine interface to HyperStudio. Several macros were added to shorten the length of the code, make it easier to read, and make it easier to compare to the high level language versions. For example, routine GetTheData was originally more than one page of code, and difficult to read, follow, or understand. It is now a few lines of code, and almost identical to the high level language versions. For QuickDraw II applications, a significant burden in assembly language is keying in the dialog templates. A new macro, DITEM, was written for that purpose. Note that operands for Merlin macros must be separated by semi-colons. The first operand for DITEM is the dialog item number. The second operand is a rectangle specification, with two points in (y,x) coordinate form. These values are separated by commas. The entire list of four numbers is treated as one operand. This was necessary since Merlin macros are limited to 8 parameters. The directory MERLIN.ASM contains the source file, macro file, object file, linker file for creating the object and load file, plus the HS.XCMD generic load file itself (file type $BC). See the Fall 1989 issue of Call -A.P.P.L.E. for a further discussion of HyperStudio XCMDs. The final Merlin version of the exerciser program file is just over 3K in length (memory required for execution). ================================================================ APW or ORCA/M Assembler This file is a direct conversion of the Merlin assembler code. Of course, many of the shortcuts of Merlin were taken out (local labels for example). The macros were rewritten and placed in the macro file. Otherwise, the code is pretty much the same. Since APW does not have a set of "super macros", the length of the source file is significantly longer. The programmer is responsible for additional stack and register manipulation to get the same job done. MOVELONG and MOVEWORD are from an early version of the macros delivered with APW. You will find two calls that use "00" as a parameter instead "0". This is due to a bug in the original macro definition. The generated code is the same. In some cases, you will find fewer comments in the APW version. This is a result of the conversion process. See the Merlin version for details. The directory APW.ASM contains the source file, macro files, object file, build file for creating the object and load file, plus the HS.XCMD generic load file itself (file type $BC). The final APW version of the exerciser program file is just over 3K in length (memory required for execution). ================================================================ ORCA/Pascal The first high level language version of an XCMD for HyperStudio was done by David Sparks. It used TML/Pascal V1.5 running under APW. However, that program could not take advantage of the subroutine interface to HyperStudio. This was discussed in greater detail in the Winter 1989-1990 issue of Call -A.P.P.L.E. The ORCA/Pascal version of HS.XCMD was the first fully functional high level language version which uses the HyperStudio subroutine interface. The modules which support accessing HyperStudio for ORCA/Pascal are in the file XCMDLIB. The source code for the library is not part of this freeware package. This is done deliberately to keep the interface standardized so all ORCA/Pascal XCMD files will use the HyperStudio subroutine interface in the same way. The compiler is V1.2. The translation from assembler language to Pascal is quite simple with one big exception. Pascal does not provide a way to build completed dialog itemtemplates at compile time. Storage is allocated by the compiler, but the values must be filled in at execution time. This is done using PROCEDURE DITEM (gee, the same name as the DITEM macro from the assembler language version). DITEM is called from PROCEDURE InitDialog (the assembler program uses InitData). The DITEM operands are taken in the same order as the operands in the assembler macro calls. However, in the assembler code, the CR macro was used as a convenient way to generate the screen position values (at the time the program is assembled). This would have required execution time code in Pascal, so the absolute screen locations were supplied instead. ORCA/Pascal is delivered with a dialogTemplate definition in the interface file DialogMgr that has room for only 10 dialog items. In order to handle the 34 dialog items here, I modified and re-compiled the DialogMgr interface file (the array bounds in ditemList was changed from 10 to 40). In order to compile this code, you will have to make this change as well. In the process of working with ORCA/Pascal, I discovered that CONCAT includes a call to an error handling routine, that adds about 2K of code to the load file. Thus, CONCAT was removed and replaced with INSERT for building InfoString for the Info dialog. The same error routine is used by CASE to handle exceptions to the CASE list, even when OTHERWISE is coded (that is, no exceptions exist). This is an error in the compiler (my opinion) and has been reported to Byte Works. To keep the size of the module small, CASE was not used. Files provided in directory ORCA.PASCAL include the ORCA/Pascal version of XCMDLIB, the program source, object, and compacted load file (OMF2, not in express load format). Examine file BUILD.PAS to see how the XCMDLIB is used. It must appear before the ORCA/Pascal PASLIB and SYSLIB (normally found in that order on prefix 2 under APW or ORCA/M). The ORCA/Pascal version uses the small memory model (default). The distributed XCMDLIB works with small memory model programs generated by the compiler (single segment). It has not been tested with large memory model programs. Do not attempt to generate normal text screen output with an XCMD file created using ORCA/Pascal and the XCMDLIB library. The programs run in a desktop environment and no provisions have been made for text screen processing. The XCMD program will fail if bank 0 memory is not available for a 2K direct page and stack. The final ORCA/Pascal version of the exerciser program file is just over 8K in length (memory required for execution). ================================================================ TML/Pascal The TML/Pascal version of the XCMD exerciser was converted from the ORCA/Pascal version. I used TML/Pascal V1.5, which runs under APW. My copy was produced before GS/OS, and does not have a complete set of updated interfaces. I also have an older standalone version of TML/Pascal, V1.something, which does not contain all the interface files. Apparently, this copy has been upgraded, but I have never received notification from TML Systems, Inc. While TML/Pascal does not appear to be the best choice of language, it does work. Use of TML/Pascal also requires an XCMDLIB file. See the BUILD.PAS file for an example of how it is used. Changes from the ORCA/Pascal version include use of the undocumented {$APW} compiler directive, which causes the Quit call to be replaced by an RTL instruction. It also allows use of the {$XRefVar+} option to get the address of the HyperStudio parameter list. Several TYPE definitions had to be added to the program since they are not part of the interface files that came with my TML/Pascal system. This includes a change to dialogTemplate for dtVisible. ORCA/Pascal defines this as boolean, which takes two bytes of memory. TML/Pascal only allocates one byte of memory for boolean, so it was changed to integer. Also, function Alertwindow is not in the interface file definitions with my copy of TML/Pascal. It was added to the program. See notes in the program listing for Rect definition usage. "Editline" in ORCA/Pascal is "editlineitem" in TML/Pascal. GetNewModalDialog generates a pointer to the dialog in ORCA/Pascal, while TML/Pascal expects an explicit pointer to be passed. GetIText and SetIText parameters are different. BITXOR is used instead of the bit operator (!), and there are changes to handle tool call errors. One other item of note: when David Sparks wrote the original TML/Pascal XCMD program, he use a modified IntMath interface file. His modification was to replace the actual string parameters with a pointer to a string. This is the expected definition as documented in the Toolbox Reference Manual. You will have to make this change also, or modify the programs passing strings to tool calls. It is important to point out that the Programmer's Introduction to the Apple IIGS also supplied this change for TML/Pascal (the HodgePodge program). Updated versions of the TML/Pascal interfaces files may have this change. At the time of this writing, TML/Pascal II was not stable enough to be used for XCMD files. Besides, I don't have a copy. Maybe next year. I have found a bug in TML/Pascal V1.5. If your subroutine references are coded as 'extern' instead of 'external', an error message is NOT generated and code is NOT generated. In other words, it doesn't work and you don't know why. 'Extern' is the ORCA/Pascal syntax for an external symbol definition. Do not attempt to generate normal text screen output with an XCMD file created using TML/Pascal and the XCMDLIB library. The programs run in a desktop environment and no provisions have been made for text screen processing. The XCMD program will fail if bank 0 memory is not available for a 2K direct page and stack. The final TML/Pascal version of the exerciser program file is just under 8K in length (memory required for execution). ================================================================ ORCA/C The ORCA/C version was generated using V1 of the compiler. It produced the smallest high level language load module, since the templates are compiled in initialized form. I encountered no special difficulties. ORCA/C provides a variable, dtItemListLength, to set the length of the DialogTemplate array, so the interface files did not have to be changed. The XCMDLIB library is different than the ORCA/Pascal library. Do not confuse them. ORCA/C has a slight problem with the case of functions. Thus, the routines had to be defined with uppercase names and called with upper case names. I expect this to be corrected in a future version of the compiler. APW/C defines "_toolErr" as the variable for tool error codes. ORCA/C users "toolerror()" to return tool error codes. The call for HiliteControl had to be split due to bad code generation. Do not attempt to generate normal text screen output with an XCMD file created using ORCA/C and the XCMDLIB library. The programs run in a desktop environment and no provisions have been made for text screen processing. The XCMD program will fail if bank 0 memory is not available for a 2K direct page and stack. The final ORCA/C version of the exerciser program file is just under 5.5K in length (memory required for execution). ================================================================ Acknowledgements This freeware package is made available through the cooperation of several individuals and organizations. They include Eric C. Mueller, David Sparks, Ken Kashmarek, Roger Wagner Publishing, Inc., Byte Works, Inc., and TML Systems, Inc. In addition: This program contains material from the ORCA/Pascal Run-Time Libraries, Copyright 1987-1988 by Byte Works, Inc. Used with permission. This program contains material from the TML/Pascal run-time libraries, Copyright 1987 by TML Systems, Inc. Certain portions of this software are copyrighted by TML Systems, Inc. Used with permission. This program contains material from the ORCA/C Run-Time Libraries, Copyright 1987-1989 by Byte Works, Inc. Used with permission. All rights associated with the original material remain with the authors and Roger Wagner Publishing, Inc. You may freely use this material for your own applications, or in the development of products for use with HyperStudio. However, you must negotiate with Byte Works, Inc. and TML Systems, Inc., for use of their libaries in your products. All contact about this package should be directed to Roger Wagner Publishing, Inc.