
     ICTARI USER GROUP             ISSUE 32                      March 1996

         ___   ______     ___       _________   _________   ___
         \__\  \   __\    \  \__    \______  \  \   _____\  \__\
           ___  \  \       \  __\     _____\  \  \  \         ___
           \  \  \  \       \  \      \  ____  \  \  \        \  \
            \  \  \  \_____  \  \____  \  \__\  \  \  \        \  \
             \  \  \       \  \      \  \        \  \  \        \  \
              \__\  \_______\  \______\  \________\  \__\        \__\

                     *   m   a   g   a   z   i   n   e   *

     =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
                       I C T A R I   U S E R   G R O U P
      63 Woolsbridge Road, Ringwood, Hants, BH24 2LX   Tel. 01425-474415
     =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

                              INDEX FOR ISSUE 32
                              ==================

     ASSEMBLY        Non-modal dialog box code.
                     Relative mouse handling routine.

     C               Dictionary game source code.

     GFA             Directory catalogue program.

     STOS            Starfield screen code.
                     Disk manager program.

     MISC            Ottos Resource Construction Set (ORCS) program.
                     ORCS review.
                     Card shuffling techniques.
                     Current membership list.
                     Index for issues 1-32.

     In next months issue of ICTARI (this may change) :-

     ASSEMBLY        Assembly Language Tutorial. Part 1.

     C               Window icon interface system.
                     File viewer program.

     GFA             Text adventure game.

     STOS            Using a large font in STOS.
                     Pie chart generator.

     MISC            Character Set Information.
                     SCSI FAQ file.
                     Programming pros and cons discussion.

     ----------------------------------------------------------------------
                                   EDITORIAL
                                   =========
     MEMBERSHIP
     ----------
     Another two members have joined the group this month, welcome to them.

     SHUFFLING TECHNIQUES
     --------------------
     In the MISC folder is an interesting  article by David Preston about a
     card shuffling algorithm, however, there is example code in Basic, GFA
     and STOS which would be of interest to programmers in any language.

     ----------------------------------------------------------------------
                                 CORRESPONDENCE
                                 ==============
     To: All
     From: Derek Warren

     I use  the  Kuma  K-spread  2   spreadsheet  program  but,   having no
     instruction manual for it, suspect that  I  don't make full use of its
     capabilities. I would be pleased to  know  of anyone who has  a manual
     which I could purchase  or,  if  not  purchase,  perhaps  borrow for a
     short time?
     ----------------------------------------------------------------------
     To: Qwen Rogers
     From: Thomas Nilsen

     The reason your GFA-GEM program will not let you enter any text in the
     editable fields is simple. The  Form_Do  expects its parameters in the
     following structure: Form_Do(tree%,first_editable_object&).  So to get
     your program to work  correctly  all  you  have  to  do  is change the
     Form_Do(tree%,0) to Form_Do(tree%,cmdline%). That  would  allow you to
     use the editable fields the way  you  want.  If you have more than one
     editable field in the form, still use  the first editable field in the
     Form_Do() command, as GEM  itself  will  handle the following editable
     fields.

     A little tip at the end. Before  you  do the Objc_Draw() make sure the
     editable fields are cleared of the Masks  you set up when creating the
     RSC file. To clear an editable field, use...

     CHAR{{OB_SPEC(tree%,cmdline%)}}=""

     This will clear the editable filed named  cmdline% and when you do the
     Objc_Draw() the cursor will be displayed at the start of the field.

     To: Jason Railton

     Reading the mouse
     -----------------
     I do not know if this is exactly   what  you want but I have written a
     small mouse-routine myself  that   I   use   in  various environments.
     I'll  include  the  full routine and if  Peter can find room for it he
     will perhaps include it in the assembly folder... Peter?

     */ See the ASSEMBLY\RELMOUSE\ folder. /*
     ----------------------------------------------------------------------
     To: ICTARI & Mrten Lindstrm
     From: Jim Taylor

     Many thanks for the advice on how   to use GDOS in conjunction with my
     drafting program MultiCAD.  This  sounds  like  an  interesting way of
     solving the  problem.

     In the meantime, for other reasons, I  still need to know how to solve
     the problem in the way I  initially  described.  Which was to send VDI
     vector graphics to a bitmap image in memory, bigger than the screen. I
     wish to implement this solution first before I resort to using GDOS.
     Does anyone know if this is actually  possible?  If so I would be most
     grateful if anyone can shed any light  on  the subject.  I know how to
     reserve a block of memory with malloc and obtain its start address but
     how do you get the VDI  to  send  the  graphics  to  it and how do you
     specify its shape eg. 800 x  2000  pixels.   v_opnvwk would seem to be
     the prime contender but it does not have size, shape, or start address
     parameters for the memory area.

     If I crack  this  one  I  promise  that  I  will  also  have  a  go at
     implementing GDOS and write an article on how I got on with it.

     To: C Singleton

      The following will send a form feed to the printer.

      lprintf("\f"); fflush(stdprt);
                        ^
      ie.       '------------->\\    backslash
                                               \'    single quote
                                               \"    double quote
                                               \?    question mark
                                               \a    audible bell
                                               \b    backspace
                                               \f    formfeed
                                               \n    newline
                                               \0    NULL character
                                               \r    carriage return
                                               \t    horizontal tab
                                               \v    vertical tab
                                               \xhhh ASCII code hhh

     Also consider the following which will cause the printer to do a cr/lf
     and reset.

      unsigned char prinit[]={13,10,27,69};
                               ^  ^  ^  ^
                               |  |  |  '-code to reset the printer
                               |  |  '-Esc. tells printer code is to follow
                               |  '----line feed code
                               '-------carriage return code

      Fwrite(3,4,&prinit);
             ^ ^    ^
             | |    '------address of data
             | '-----------number of characters to send
             '-------------output device (printer).

     ----------------------------------------------------------------------
     To: Peter Hibbs
     From: John Cove

     If I recall you could not  get  the  68000  "game" to work.  Well, you
     will notice that the code loads  up  a  data file, before it runs. The
     loader will NOT work from a  hard  disk,  so  you must run it from the
     disk.  So, look for the fname line on line 770, reading;

     fname           dc.b    'saucers.dat',0

     change it to:-

     fname           dc.b    'a:\assembly\saucers\saucers.dat',0,0,0

     ...and you will find it works fine!

     */ As you say, it  works  fine,  quite  what  it  is  supposed to do I
     haven't worked out yet. Anyway I think  there is a lesson here for all
     programmers, make sure your code  will  work from any folder/drive for
     maximum user friendliness.  PDH /*
     ----------------------------------------------------------------------
     To: Anyone
     From: Owen Rogers

     Thanks to some of the  members  for  helping  me out with the editable
     strings!.  I'm making a drop down  menu  program  in GFA Basic 3 where
     you click on the menu entries and dialog boxes pop up.  When you click
     on the Exit button you are returned  to  the menu again to select some
     thing else.  The problem is that when you select the same dialog twice
     in the program the button on  the  dialog  box is already selected and
     you have to deselect and then select the button again to exit.  Please
     can anyone help me because I am  hoping  to release it into the public
     domain and it looks really terrible with this problem.  I use the ORCS
     resource editor.

     */ This is a  fairly  straightforward  problem,  the  routine needs to
     remember the object number of  the  button  that  was used to exit the
     dialog and then just  before  you  exit  the  dialog  routine, use the
     number to locate the  object  data  and  clear  bit  0  in the 'object
     states' field (offset 11). This subject  was  covered in the GEM Guide
     Part 4 article by Mrten Lindstrm  (Ictari  28) but if anyone has any
     further information about  this  in  GFA  Basic,  please  send  it in.
     ICTARI /*
     ----------------------------------------------------------------------
     To: *.*
     From: John Levon

     If you have Web access, you can examine the ICTARI Web page at :-

     http://www.cs.man.ac.uk/~levonj5/movement/ictainde.htm

     To: ICTARI

     Could you  possibly  from  now  on  rename  all  ICTARI.TXT  files  as
     ICTARIXX.TXT  where  XX  is  the  issue  number?  As  I  save  all  my
     ICTARI.TXTs this would make storing them a mite easier.

     */ Thanks for the Web page.  I  can't  see any problem with adding the
     issue number to the filename, I'll just  have to worry about issue 100
     (November 2001) if we are still going then.  ICTARI /*
     ----------------------------------------------------------------------
     To: All
     From: Tony Harris

     1) I am writing a  program  that  extensively  uses rasters, however I
     need to use the mouse but  the  rasters  become very unstable when the
     mouse is moved, I understand (through  this  column) that I would need
     to  make  the  mouse  interrupt  a  lower  priority  than  the  TimerB
     interrupt, but how?

     2) Just out of interest,  when  were  Blitter  Chips  put into ST's as
     standard?

     */ We have published some code using rasters in issues 4, 5, 13 and 20
     which may be of help. If anyone has any more info, please let us know.
     I believe the  blitter  was  first  included  in  the  STe  machine as
     standard.  ICTARI /*
     ----------------------------------------------------------------------
     To: David Preston
     From: Jason Railton

     Re: SeaPest.PRG

     Not being able to run the compiled  .PRG  sounds to me like a STOS/TOS
     incompatibility  problem.   The  symptom   you   described  (no  mouse
     response) is the sort of  thing  STOSFIX  is  able to rectify.  Do you
     have a copy? If you do, could you try it on my .PRG?

     If you don't have TOS  2.06,  but  an  earlier version, it should have
     worked.  As far as I know,  I  have  the latest versions of STOS (2.6)
     and the compiler (2.5).  Can anyone else help?

     To: C. Singleton

     Re: Form feeds to a printer in C.

     Have you  tried  simply  printing  the  ascii  character  CHR$(12), or
     whatever the C equivalent is, on the printer?

     To: Peter Hibbs

     Re: GEM and AUTO programs.

     You're right in thinking that you  can't  use  GEM and VDI calls in an
     AUTO folder program, because it will  execute before GEM is installed.
     However, you can use all the  TOS  calls (BIOS, XBIOS, even GEMDOS) so
     you can alter memory  allocation  and  access  the  disk  from an AUTO
     program.

     If you really need the  GEM  and  VDI  in your TSR's startup sequence,
     there is a way round the problem, but  it's only a dodgy theory at the
     moment...

     1. Write a TSR routine that installs itself in the GEMDOS trap (#1).

     2. This routine should check to see if  GEM is up and running (look in
     COMPUTE!'s for a  suitable  system  variable,  or  check  the GEM trap
     vectors for initialisation, or something).  GEM is bound to use GEMDOS
     at some point even without user  input,  if only to check the keyboard
     buffer.

     3. Once it spots  GEM  is  installed,  a  second  installer routine is
     called that can restore the GEMDOS  trap,  and establish your main TSR
     program. This can either be run from  disk  by the first TSR, or could
     have been part of the original AUTO  program.  You can then use GEM in
     the setup and installation of your main TSR.
     ----------------------------------------------------------------------
     To: Jason Railton
     From: Stephen Bruce

     I couldn't get the mouse to work on the STOS Polygon demo on issue 31.
     Is this a compatibility problem with  STOS  and STe's or a bugged copy
     of the program.

     */ On my STFM (TOS 1.04) I  just  get  a black screen and nothing else
     happens !  PDH /*
     ----------------------------------------------------------------------
     To: *.*
     From: Mrten Lindstrm

     Thanks to all of you who have  responded  to what I have written about
     GEM programming. It is very rewarding  to hear that someone is reading
     what one writes, and completely wonderful when it is appreciated too.

     I must point out, however, that I  have little or no actual experience
     of programming for MiNT, MultiTOS, MagiC or  Geneva, my own ST being a
     bit small (1 Mb) for them.  So  any  experiences - by members who have
     run, and programmed for, these - would be highly valuable.

     One small thing  that  I  became  aware  of,  only  after writing that
     global[1]=1 for "singleTOS" and  =-1  for  MultiTOS,  is that it might
     also =16 for MagiC. The reason  for  this  would be that global[1] was
     documented as the maximum number  of concurrently running applications
     (not counting accessories), which is  infinite for MultiTOS and Geneva
     but apparently limited  to  16  for  MagiC.  Could  someone with MagiC
     confirm this?

     In any  case,  when  looking  for  MultiTOS  capabilities,  you should
     probably look for ANY (non-zero) value not equal to 1.

     To: *.*
     From: Mrten Lindstrm

     ATARI WORLD
     -----------
     I have so far not seen a copy  of the new Atari World magazine where I
     live. But from all the talk about  it,  it seems to be good (while the
     value of ST Applications was of  course greatly reduced on the leaving
     of Jon Ellis).
     Could someone tell me what the subscription price is, for us EUROPEANS
     OUTSIDE THE UK. And perhaps  give  me  an  address  to which to write,
     should I afford it.

     To: *.*
     From: Mrten Lindstrm

     PAGE DESCRIPTION LANGUAGES AND WORD PROCESSOR FILE FORMATS
     ----------------------------------------------------------
     I have now got the  complete  specification  from  Microsoft for RTF -
     Rich Text Format (v1.3).  Apparently  it  is freely distributable, but
     unfortunately not in ASCII format  -  making  use of various fonts and
     styles - so I am now converting  it  to ASCII (and also tidying up the
     slightly corrupted layout of some tables).
     I intend to send it in next  month together with some related material
     (I hope Ictari will  find  room  for  it  all,  but  then there is the
     possibility to compress it).

     Does  anyone  have   specifications   for   other   text  formats/page
     description languages - HTML,  SGML,  Post  Script  etc.  - and if so,
     could you please send them in to Ictari?
     (At  least  HTML  specifications  should  be  available  somewhere  on
     Internet, shouldn't they?)

     As for simple word processor formats,  If  anyone is interested in how
     Protext files are constructed, I  could  say something about that too.
     (Though I have only got v5.51 and don't know how v6 does with pictures
     for instance.) Anyone else who knows (or  wants to know) about this or
     other word processor - or DTP - formats?

     To: *.*
     From: Mrten Lindstrm

     UNICODE - THE ASCII OF TOMORROW
     -------------------------------
     The topic of character sets  has  been  covered  before in Ictari, but
     recently, when  paging  through  some  (PC)  magazines,  I  found some
     information that was previously completely unknown to me.

     We  have  all  become  used  to  ASCII  (American  Standard  Code  for
     Information Interchange) being  the  standard  for  character encoding
     (the only pre-ASCII set that could possibly still be encountered is, I
     think,  something  called  EBCDIC  -  Extended  Binary  Coded  Decimal
     Interchange Code - of old IBM mainframes).

     ASCII lets each character be represented  by  a BYTE, of which however
     the uppermost bit is  unused  in  pure  ASCII,  limiting  the range of
     possible codes to 0 through  127.  Since, in addition, characters 0-31
     and 127 are reserved for use as control codes (or application specific
     purposes) there are only 95 actual ASCII CHARACTERS, 32-126.
     This excludes  all  modified  ("non-English")  Latin  letters  of, for
     instance, Swedish,  and  also  the  British  pound  sign  (though  the
     American dollar sign IS an ASCII character).

     The reason the uppermost bit was kept clear,  was for it to be used as
     a parity  bit  during  serial  transmission.  In  the  days  when  all
     computers were mainframes, communicating  with  stupid terminals, (and
     also before  today's  transmission  protocols),  this  was  absolutely
     essential, but today is not  nearly  as  often  needed. So all present
     personal computers do make use  of  all  bits  of  each byte, giving a
     further 128 possible characters (128-255).
     Unfortunately, when this second half of  the 8-bit set was filled with
     characters, there was not much  coordination or planning, resulting in
     a number of DIFFERENT 8-bit character  sets,  mapping one and the same
     character to different code numbers.

     Also, there are so  many  characters  and  symbols,  you might want to
     implement, that even these  extra  128  characters  may  not be enough
     anyway. Thus, special  character  sets  with  only  symbols  have been
     defined - e.g.  Dingbats  -  and,  above  all,  a  limitless number of
     character set variations to support non-Western languages.
     Not only does this create a lot of confusion when porting text between
     different computers or  countries,  but  when  you  come  to East Asia
     (China/Japan/Korea) - with  thousands  of  characters  -  adherence to
     ASCII can only be maintained  if  some  characters (including the true
     ASCII ones) are one-byte,  while  others  are  implemented as two-byte
     characters,  complicating   programming   (and   also   slowing   down
     performance).

     Enter Unicode! This new standard,  backed  by all the leading computer
     companies and since 1993 by ISO, simply lets each character be encoded
     in a WORD (16 bits), instead of  a  byte.  And all of a sudden we have
     65536 characters - more than  enough  for  all living languages of the
     world, and few dead ones too;  plus  a vast number of mathematical and
     other symbols. And, best of all,  it  will  be  as easy to program for
     Unicode as for ASCII. In C you  may  even be able to write source that
     can be used for either, if  merely  the variable type "char" (=a byte)
     is replace with a 16-bit type  (for some reason called "wchar_t"). All
     the old conventions and techniques  can  then  be applied to Unicode -
     such as terminating character strings with  a NULL (though a null WORD
     rather than a null BYTE).

     WHAT A WASTE - you may think  -  to  allow text to gobble up twice the
     memory and disk space  it  needs  as  ASCII.  But the reasoning behind
     Unicode is, of course, that in the age of "Multimedia" it is not text,
     but images and sound that are gobbling up most of what space there is,
     and Unicode won't change that  much.  (Also: if COMPRESSING text data,
     they should end up the same  size,  whether originally 8-bit or 16-bit
     encoded, if otherwise identical).

     Don't doubt that Unicode WILL  be  THE standard for character encoding
     in the  future.  Again,  in  the  choice  between  simple  Unicode and
     multiple 8-bit sets (and  convoluted  variable-width  encoding of East
     Asian languages) the leading  computer  companies have clearly decided
     the future to  be  Unicode.  On  PCs,  Windows  NT  - the heavy-weight
     version of Windows - (though not  Windows 95) already uses Unicode for
     most of its internal text handling.

     One problem with WORD encoding is the different way in which Intel and
     Motorola processors store words, requiring  the  bytes of each word to
     be swapped if imported from a "foreign" processor. Unicode solves this
     with a special BOM (Byte Order  Mark) character $FEFF, normally stored
     as the very first word of a  "plain  Unicode text" file. Now, should a
     reader encounter the byte-swapped form, $FFFE, this should be taken to
     signal a foreign processor format, since  $FFFE itself is NO CHARACTER
     under Unicode and shouldn't occur in Unicode text.

     So, how does this concern us who program  for Atari? As far as I know,
     there is no Unicode support yet  offered  by any TOS extension, but it
     must be only  a  matter  of  time  before  SpeedoGDOS  and  NVDI start
     supporting it. The  GDOS/VDI  functions  of  these  for OUTLINE fonts,
     already support 16 bit character encoding, though unfortunately so far
     using  only  the  completely  non-standard,  font-dependent,  internal
     character INDEXES  of  each  font.  Microsoft  has,  however, recently
     published specifications for a new  pan-European True Type font, WGL4,
     with 652 characters, referred to  by Unicode numbers, and Atari/Compo-
     /2B simply have got to make use of that.
     In the meantime, if you are  writing  a  word processor or similar, it
     may be a good idea to at least  try  to write the code to be as easily
     convertible to 16-bit characters as  possible, to prepare yourself for
     the future. If you are willing  to  convert between Unicode and Speedo
     indexes, or even do the  character  rendering yourself, you might even
     start programming for Unicode now.

                                    +++<>+++

     Also see the file CHARSETS with  lists  of  all the common 8-bit sets,
     better than the ones I  have  previously  sent,  plus some Unicode and
     Speedo material. And if anyone knows more, please share!

     To: *.*
     From: Mrten Lindstrm

     AES CALLS UNDER SUPERVISOR MODE
     -------------------------------
     According to Laurenz Prner  in  the  German  "ST  Magazin" 5/91, AES
     calls are officially allowed also  in  supervisor mode provided that a
     number of precautions are taken:

     1)      A number of AES functions  (undocumented which ones) return in
             USER MODE. So the program must, after each AES call, check the
             processor mode  (with  SUPER(-1))  and  if  necessary  restore
             supervisor mode.

     2)      A special supervisor stack, separate from the user stack, must
             be used. (Thus you cannot,  according to common practice, make
             your user stack pointer into a supervisor stack pointer). This
             is because the AES has  the  peculiar  habit of saving data on
             the user stack regardless of the  processor mode, and when the
             USP points in about the same memory  area as the SSP, data may
             be overwritten.

     3)      At the very  least  12  free  bytes  must  be  available ABOVE
             (AFTER) the  super  stack  pointer,  since  the  AES  has  the
             peculiar habit of writing after the stack.

     To: *.*
     From: Mrten Lindstrm

     TSR programs
     ============
     Using GEM functions from within a TSR  program is not trivial I think.
     The problems would be:

     1)      AES calls  in  supervisor  mode  (under  which  a  TSR program
             normally is working) need special precautions, see above.

     2)      In whose name is the TSR program to make its call?

             During the installation (taking place  when the TSR program is
             executed from the AUTO folder),  a TSR program cannot register
             itself as a GEM application with APPL_INIT, nor make any other
             GEM  calls,  since  all  this   happens   before  the  GEM  is
             initialized.

             And after terminating the installation, with PTERMRES, the TSR
             program doesn't even exist as a GEMDOS process any more (it is
             merely a "dead" block of  memory, containing some sub-routines
             for the system, to  which  some  system  vectors  happen to be
             redirected).

             On the other hand, this may not be a problem at all. Maybe the
             TSR program (or rather an installed routine of it) CAN bluntly
             call APPL_INIT, after the  initialization  is done. (Not being
             GEMDOS processes doesn't prevent  ACCESSORIES  from making GEM
             calls).

     That there has to BE a solution  is  proved by, for instance, new GDOS
     versions (e.g. the AMCGDOS program on  Ictari 25) which are capable of
     calling up AES ALERT BOXES to show their error messages.

     Maybe someone could experiment  with  calling  APPL_INIT and other AES
     functions from a TSR  routine.  (Or  else  disassemble AMCGDOS or some
     other existing TSR that uses GEM).
     Should this not work, I guess the  TSR  will have to hook into the GEM
     vector  (TRAP 2),  watch  others   install   themselves,  copying  the
     necessary data, and then somehow pose as another real GEM process.

                                   ---------
     A perhaps simpler solution maybe, as Peter Hibbs suggested, is to make
     the TSR into a GEM accessory instead.
     Or maybe a COMBINATION of TSR  program  and ACC. The TSR program would
     do the dirty  work  of  redirecting  vectors,  installing  cookies and
     generally allocating memory for new  routines and data structures. The
     ACC would take care of the  GEM  interface. Contact between them could
     be made for instance via  some  address  that  the TSR advertises in a
     cookie.

     Jason Railton also contributed many valid suggestions on this subject,
     but on points 1 and 4 I disagree:

     1) The proposed structure of a new routine was

         new_routine:  bra     do_stuff
         old_vec:      ds.l    1
         my_id:        dc.b    "MY_PROG "
                       even
         do_stuff:
         * Your routine...

     However, there now exists a STANDARD,  called the XBRA protocol, which
     instead prescribes the following structure:

                      dc.b    "XBRA"    ; XBRA protocol identifier
                      dc.b    "MyID"    ; 4-byte ID unique to program(mer)
         old_vec:     ds.l    1
         new_routine:
         * Your routine...

     I.e. the ID and old vector  should  PRECEDE and not follow the address
     of the new routine. (Not that it  wouldn't be possible to combine both
     structures, but that would be a bit redundant).

     The XBRA protocol was probably invented (or at least established) only
     AFTER the Compute book, referred to,  was  written.  But it is now the
     established standard  among  all  professional  Atari  programmers,  I
     think. (Also see the assembly folder in Ictari 30).

     The advantage of using a general  standard  is of course that not only
     your OWN program can determine whether it was previously installed and
     what the old vector was, but any other program can do the same. If ALL
     programs, that redirect vectors, use the XBRA protocol this also means
     that, by tracking the linked list of XBRA routines back you can:

      A)     find your own routine EVEN  if  other programs have afterwards
             redirected the same vector again.

      B)     find the ORIGINAL (ROM) vector.

     For any system vector you  can  check  if  the  long  at offset -12 is
     "XBRA", and if so be certain that  the  long at offset -4 contains the
     previous vector.

     In particular  if  you  want  your  programs  to  work  well  with  OS
     extensions such as MiNT etc.  I  think  the  XBRA protocol can be very
     valuable.

     (For ACCESSORIES, if  not  for  TSR  programs,  adherence  to the XBRA
     protocol determines whether or  not  the  CHAMELEON  accessory will be
     able to unload them).

     ------------
     4) To wait for the space bar  to  be pressed the following routine was
     suggested:

         wait_space_bar: cmp.b    #$39,$FFFFFC02.W
                         bne.s    wait_space_bar

     But ANY direct hardware access  should  come  with the warning that it
     might impair compatibility. And if,  as  in  this case, there exists a
     system call that can achieve the  same  thing, I think you should have
     VERY good reasons before you forego the system call.

     (You may find this remark finical,  and  it  is true that the proposed
     routine will probably work on  all  existing  Atari machines. But I am
     not so sure that it will work with, for instance, the MagicMac.)

     An entirely equivalent system call version is:

         wait_space_bar: move.l     #$20002,-(SP) ;BCONIN - Console
                         trap       #13
                         addq.l     #4,SP
                         cmp.b      #$39,D0
                         bne.s      wait_space_bar

     and will cost you 16 bytes assembled  code, as compared to the 8 bytes
     of the first version, but I still think  it is worth it in the general
     case. (Your situation will of course  be  different if you are writing
     an action type game or animator or  anything else that requires you to
     abandon compatibility ambitions anyway).

     Then again, although this is a matter  of  personal taste, I as a user
     am not too hot on the idea of TSR programs halting the boot process at
     all, and if anything would prefer something like:

         test_any_key:   move.l     #$10002,-(SP) ;BCONSTAT - Console
                         trap       #13
                         addq.l     #4,SP
                         tst.b      D0
                         beq.s      test_any_key

     which would check - NON-DESTRUCTIVELY -  for any key press. This would
     allow the user to press any key  ONLY ONCE to possibly bypass multiple
     TSR programs that are using the above routine.

     Of course, what a TSR program  should  NOT  do  is to clear the screen
     before it shows  its  installation  message.  That would unnecessarily
     erase the messages of  previous  TSR  programs  (and  yet  I have come
     across a few programs that do this).

     ------------
     To: David Preston
     From: Mrten Lindstrm

     Yes, with OBJC_DRAW you can, just  as  well as the full dialog, redraw
     only a part (subtree) of it by  using  the object number of the parent
     of the part (subtree root).

       objc_draw(treeaddr,subtree_root,objdepth,xclip,yclip,wclip,hclip)

     If for instance the object number of  a  slider bar is used here (with
     an object depth of 2 or more)  then  the slider bar and its child, the
     slider, will both be redrawn but no other parts of the dialog.

     You don't, for this call, need  to  know  the exact screen position of
     the object. As a clipping rectangle  you  can use the rectangle of the
     full  dialog  box,  or  even  of  the  full  screen  (as  returned  by
     WIND_GET(0,5,...)). If drawing in a window you would probably use each
     of the "visible rectangles" got with WIND_GET with modes 11 and 12.

     But when you DO need  the  screen  position,  you are absolutely right
     that the way to get it is  with  OBJC_OFFS  for the x and y, by direct
     reading of the object structure for  the  w  and h. (Direct reading of
     the X and Y, on the other hand, will  give you the x and y relative to
     the parent rather than relative to the screen).

     The width  and  height  are  in  the  last  two  words  of  the object
     structure, i.e. at offset 20 and 22.  E.g. to access the width you can
     use:

             address of object width = treeaddr + objnum*24 + 20

     To: Jim MacLeod
     From: Mrten Lindstrm

     form_keybd(tree%,edobj,key,nextobj,newobj,key)  (AES function 55)
     ----------
     form_keybd RETURN <-  int_out[0]
          tree%         -> addr_in[0]
          edobj         ->  int_in[0]
            key IN      ->  int_in[1] (assembly:  int_in+2)
            key OUT    <-  int_out[2] (assembly: int_out+4)
        nextobj         ->  int_in[2] (assembly:  int_in+4)
         newobj        <-  int_out[1] (assembly: int_out+2)

     (Reference: Chapter 4 of  the  GEM  Guide,  in  Ictari  28,  - see the
     function description and the FORM_DO REPLACEMENT routine.)

     An interesting discovery  is  that  the  "nextobj"  input  variable is
     simply copied to the  "newobj"  output  variable  if  no new object is
     selected by the user. And that this can be used to determine WHETHER a
     new object WAS selected.

     The same thing can, however,  also  be  determined from the FORM_KEYBD
     FUNCTION  RETURN  value  (int_out[0])   and   the   OUTPUT  KEY  value
     (int_out[2]). If the  former  is  zero,  then  Return  was  pressed (=
     selection of the default  exit  object),  otherwise  if the output key
     value is zero then some other object was selected through press of Tab
     or arrow keys.
     (Otherwise the output key value can be passed on to OBJC_EDIT).

     The recommendation to always  use  1  for  nextobj  was actually AC's,
     although your observation seems  to  imply  that  instead setting it =
     edobj could possibly save us a line of code -
     (namely the  "Let newobj=edobj"   if  object  wasn't  pressed; see the
     FORM_DO REPLACEMENT routine)
     - ensuring that newobj is always the current object whether changed or
     not.

     POINTER OFFSETS AND ARRAY INDEXES
     ---------------------------------
     Just to  avoid  misunderstandings  between  programmers  of  different
     languages, when we are dealing with a WORD array such as int_out:

          int_out+2   in assembly (or
     WORD{gintout+2}  in GFA Basic 3)

     refers to the same word as

          int_out[1]  in C
     or   gintout(1)  in GFA Basic 3

     and even to the same word as

        *(int_out+1)  in C   (due to the TYPED pointers of C)

     Assembly programmers have a tendency, I think, to confuse the assembly
     pointer expression int_out+2 with array element int_out(2) (correspon-
     ding to assembly int_out+4).  For  instance,  this  mistake is consis-
     tently made  in  Katherine  Peel's,  otherwise  excellent,  book  "The
     Concise Atari ST Programmer's Reference Guide"  - the book I have used
     the most over the years.

     */ The Atari World magazine is  quite good, especially the programming
     articles. As I happen to have a spare  copy  of issue 9 I have sent it
     on to you, the subscription information for Sweden is on page 41.

     I would be very interested  in  publishing  the information on RTF and
     any other text formats as well,  this  is the sort of information that
     can be very useful to programmers.  Perhaps  any member with access to
     the Internet could look out for any PD material which may be of use to
     programmers, even PC or MAC information  of  a general nature could be
     of interest to Atari users.

     The Unicode system sounds  very  interesting  (the  character set info
     will be in next months issue),  does  anyone else have any comments on
     this. The only problem that  I  can  see  is  that  GEM uses byte size
     characters, will an application using Unicode  and GEM have to convert
     every text string from word  size  to  byte  size before calling a GEM
     text function?

     Incidentally, the word 'finical' used by Mrten above means finicky or
     fastidious and is not a word  used  much  in English although it is in
     the dictionary.  ICTARI /*
     ----------------------------------------------------------------------
     To: All
     From: Peter Hibbs

     I am writing a program which uses sprite graphics in low rez mode only
     and I need to compress the graphics  file in RAM to save memory space.
     The compression time is unimportant  as  this  is only ever done once,
     the decompression time needs to  be  fairly  fast  (although it is not
     that critical) and  the  compression  ratio  needs  to  be  as high as
     possible, i.e. the compressed data needs  to be as small as posssible.
     Does anyone have any  ideas  on  the  best  compression method to use?
     Since there are always 4 planes, the sprite data size will always be a
     multiple of 8 although the size  of  each  sprite will vary. I suspect
     that the 'Run Length  Encoding'  method  testing  one  plane at a time
     (using word sizes) would be OK unless anyone knows of a more efficient
     method.

     In the same program I  need  to  display  a  sprite  as a mirror image
     (flipped horizontally). It is not  too  difficult to modify the sprite
     routine to display the graphics data  starting from the right (instead
     of the left as normal) but I  would  also need to reverse the order of
     the bits in each word, for example :-

             the word -      0010111001001101
     would change to  -      1011001001110100

     The problem is that I need to do this very quickly in real time and as
     there are thousands of words in  some sprite images, time is critical.
     I just cannot see any  easy  way  to  do  this quickly even in machine
     code.

     For example, one method would be to shift  each  bit out to the C or X
     registers using ROXR and then shifting them back into another register
     with ROXL but since this operation can only be done one bit at a time,
     it would need at least 32  instructions  for each word plus some other
     overheads. This could be done a byte at a time but would still be time
     consuming. Another method would be  to  use  a  look up table but this
     would need to have 65535 entries (or  256 for byte sizes) and would be
     a bit impractical.  I  was  hoping  there  would  be some mathematical
     relationship between the two values that  I  could use to convert from
     one to the other but  I  can't  see  one.  Does  anyone have any other
     ideas?

     ----------------------------- Advertisment ---------------------------

     For Sale. AutoSwitch Overscan Unit.  20 o.n.o.  (was 50 new).

     This a hardware device which increases  the  size of the screen in all
     three resolutions. Only  works  on  STFMs  (not  STEs  or Falcons) and
     requires  some  soldering  and  track  cutting.  Includes  manual  and
     software.

     Contact Peter Hibbs on 01425 474415.

     ------------------------------ End of file ---------------------------
